Выберите 1000 различных имен из 100 миллионов записей через стандартный sql

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

Как мне как можно быстрее выбрать 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
    

person whytheq    schedule 29.03.2013    source источник
comment
Вы можете найти это полезным stackoverflow.com/questions/595123/, но могу ли я спросить, каково намерение иметь таблицу tb_FirstName, полную дубликатов?   -  person bummi    schedule 29.03.2013
comment
@bummi, этот вопрос - упрощенный пример реальности - таблица на самом деле имеет 30 полей, но не нужно включать это в вопрос   -  person whytheq    schedule 29.03.2013
comment
100ММ имен? звучит как спам / маркетинговая база данных личной информации ... не уверен, поможет ли вам или нет   -  person Remus Rusanu    schedule 29.03.2013
comment
@RemusRusanu, у нас много пользователей за последние 10+ лет. Не спам и не маркетинг. Просто анализ.   -  person whytheq    schedule 29.03.2013
comment
Для анализа вы должны выделить все отдельные имена в отдельную таблицу один раз, а затем присоединиться к ней по желанию.   -  person Remus Rusanu    schedule 29.03.2013


Ответы (5)


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

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

Condensed SQL Fiddle Demo

person sgeddes    schedule 29.03.2013
comment
@whytheq - нп, мы рады помочь! - person sgeddes; 29.03.2013
comment
К вашему сведению: не работает с столбцами, которые нельзя сравнивать, например XML или TEXT. - person Maury Markowitz; 22.01.2019

Попробуй это

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 

or

SELECT DISINCT TOP 1000 FirstName
FROM WHData.dbo.tb_DimUserAccount ORDER BY FirstName
person Harshil    schedule 29.03.2013
comment
Второй подход очень привлекателен. Это аккуратно и аккуратно. Плюс очень читабельный. - person Oybek; 29.03.2013
comment
OP запрашивает стандартный SQL, а ROW_NUMBER() OVER(PARTITION... выглядит как функция tSQL. - person Artemix; 29.03.2013
comment
Во-вторых, я считаю, что это стандарт ANSI. - person Jason Carter; 29.03.2013

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

SELECT TOP 1000 FirstName
FROM (SELECT DISTINCT FirstName
FROM dbo.tb_DimUserAccount) N
ORDER BY FirstName
person Nick    schedule 29.03.2013
comment
Повышения производительности нет, поскольку в подзапросе выполняется полное сканирование таблицы. Это то же самое, что и сообщение. - person Romil Kumar Jain; 29.03.2013
comment
Правда, полное сканирование таблицы по-прежнему требуется, но производительность немного выше, чем при публикации. - person Nick; 29.03.2013

Данные вам понадобятся после сортировки результатов по полям FirstName.

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

person Romil Kumar Jain    schedule 29.03.2013
comment
2+ Джона - не редкость - person Oybek; 29.03.2013
comment
Мы не можем разместить кластеризованный индекс, поэтому уникальный индекс будет иметь лучшую производительность, чем обычный некластеризованный индекс. - person Romil Kumar Jain; 29.03.2013
comment
Уникальный индекс подходит только в том случае, если целевой столбец содержит только уникальные элементы. Судя по названию столбца FirstName, это маловероятно. - person Oybek; 29.03.2013

Вариант с предложением GROUP BY

SELECT TOP 1000 FirstName
FROM WHData.dbo.tb_DimUserAccount
GROUP BY FirstName
ORDER BY FirstName
person Aleksandr Fedorenko    schedule 29.03.2013