2013-03-29 2 views
3

У меня есть таблица tb_FirstName с одним полем FirstName. Таблица содержит 100 миллионов ненулевых записей с большим количеством повторений, например. Джон встречается 2 миллиона раз. Различный счет FirstName составляет более 2 миллионов.Выберите 1000 различных имен из 100 миллионов записей по стандарту sql

Как выбрать 1000 различные имена как можно быстрее, используя стандартный SQL?

настоящее время я использую следующие, но это

  • Tsql
  • Может быть, не так эффективно, как это могло быть.

    SELECT x.FirstName 
    FROM (
        SELECT FirstName, 
          rnk = RANK() OVER (ORDER BY Firstname) 
        FROM WHData.dbo.tb_DimUserAccount A 
        GROUP BY FirstName 
        ) x 
    WHERE rnk <=1000 
    
+0

Вы могли бы найти это полезным http://stackoverflow.com/questions/595123/is -there-ansi-sql-alternative-to-the-mysql-limit-keyword, но могу ли я спросить, каково намерение иметь таблицу tb_FirstName, полную дубликатов? – bummi

+0

@bummi этот вопрос является уменьшенным примером реальности - таблица фактически имеет 30 полей, но не нужно включать это в вопрос – whytheq

+0

100MM имен? звучит как спам/база данных маркетинга личной информации ... не уверен, если вам помочь или нет –

ответ

6

Похоже, вы могли бы использовать TOP 1000 с DISTINCT:

SELECT DISINCT TOP 1000 FirstName 
FROM WHData.dbo.tb_DimUserAccount 
ORDER BY FirstName 

Condensed SQL Fiddle Demo

+0

+1 так же просто - спасибо – whytheq

+0

@whytheq - np, рад, что мы сможем помочь! – sgeddes

1

Убедитесь, что индекс, определенный на FirstName.

SELECT TOP 1000 FirstName 
FROM (SELECT DISTINCT FirstName 
FROM dbo.tb_DimUserAccount) N 
ORDER BY FirstName 
+1

Отсутствие улучшения производительности, поскольку в подзапросе выполняется полное сканирование таблицы. Это то же самое, что и сообщение. –

+0

Правда, сканирование полного стола по-прежнему требуется, но производительность несколько лучше, чем пост – Nick

1

Вам нужны данные после сортировки результатов по FirstName полей.

Для этого требуется полное сканирование таблицы, если индекс не создан. Если Index создается по первому имени, то уникальное сканирование индекса может улучшить время.

+1

Индекс не обязательно является уникальным. – Oybek

+0

2+ Джон не является редким сценарием – Oybek

+0

Мы не можем поместить кластерный индекс, поэтому уникальный индекс будет иметь лучшую производительность, а не обычный некластеризованный индекс. –

3

Попробуйте

SELECT TOP 1000 FirstName FROM 
(SELECT 
ROW_NUMBER() OVER(PARTITION BY FirstName ORDER BY FirstName) NO, 
FirstName FROM WHData.dbo.tb_DimUserAccount) 
    AS T1 WHERE no =1 

или

SELECT DISINCT TOP 1000 FirstName 
FROM WHData.dbo.tb_DimUserAccount ORDER BY FirstName 
+0

Второй подход очень привлекателен. Это аккуратно и точно. Плюс это очень читаемо. – Oybek

+2

OP запрашивает стандартный SQL, а 'ROW_NUMBER() OVER (PARTITION ...' выглядит как функция tSQL. – Artemix

+0

+1 для второго подхода - мне нравится ANSI – whytheq

0

Вариант с GROUP BY п

SELECT TOP 1000 FirstName 
FROM WHData.dbo.tb_DimUserAccount 
GROUP BY FirstName 
ORDER BY FirstName