2015-04-06 7 views
-2

Для целей этого вопроса результаты или точность этого не имеют значения. Я просто хочу знать, можно ли запросить, скажем, первые 1000 строк таблицы. Это может привести только к 100 результатам или может вернуть 1000. Я не хочу явно ограничивать результаты, но только количество запросов.Возможно ли ограничить количество зарегистрированных запросов?

+0

'ВЫБРАТЬ TOP 100 * FROM table' – Lamak

+1

Нет, что ограничивает результаты. Правильно? –

+8

Вы - пользователь 2.5K. Почему удаление предыдущего вопроса и добавление другого. Вы знаете, что вы всегда можете редактировать и уточнять. –

ответ

8

Поскольку вы d не заботясь о том, какие результаты вы получите, я достигаю tablesample в этих сценариях.

Вы можете использовать TABLESAMPLE быстро возвращать образец из большой таблицы, когда выполняется одно из следующих условий:

  • Образец не должен быть действительно случайной выборки на уровне индивидуального строк.
  • Строки на отдельных страницах таблицы не коррелируют с другими строками на одной странице.
SELECT DISTINCT 
    D.SomeValue 
FROM 
    dbo.MyTable AS D TABLESAMPLE(1000 ROWS); 

Что произойдет в том, что ядро ​​базы данных собирается захватить около 1k строк, а затем процеживают. Как это получается, эти строки не имеют значения, потому что вам все равно, вы просто хотите заглянуть за уникальными значениями в этом наборе данных.

Возможно, вам потребуется запустить это несколько раз. Первые 3 пробега против моей таблицы строк 16M не дали никаких результатов.

И для получения дополнительной информации по этому вопросу нет результатов, есть отличная рецензия Sampling Using TABLESAMPLE ч/т до Martin Smith

+1

Что? Это именно то, чего я хотел. Я не знаю, в восторге или в ярости! –

+1

Я понятия не имел, что 'TABLESAMPLE' даже существовал; это такие сообщения, которые всегда заставляют меня задаться вопросом, что еще мне не хватает. – LittleBobbyTables

+0

Хорошее решение! Один вопрос, хотя и может быть (читайте: возможно, я) просто неверно истолковал: «Первые три пробега против моей таблицы 16M не дали никаких результатов». Означает ли это: у вас нет отличных результатов (hrm), никаких результатов вообще, а не результатов, которые вы искали, или чего-то еще? – Mackan

2

Если вы хотите только первые 1000 строк таблицы, одна возможность заключается в том TOP как предложено Lamak:

select top 1000 * from MyTable 

В приведенном выше запросе TOP будет возвращать до 1000 строк в неопределенном порядке. Если число строк меньше 1000, оно вернет количество строк в таблице. Если вам нужен верхний N, использующий какой-то порядок, используйте ORDER BY.

Например, следующий запрос возвращает верхние 1000 строк из последнего первого:

select top 1000 * from MyTable order by EntryDate desc 

Следует отметить, что введение ORDER BY может вызвать дополнительную операцию сортировки. Возможно, вам понадобится индекс в этом столбце, если таблица очень большая.

Если вы также управляете кодом клиента, возможно, вы можете реализовать это как серию асинхронных вызовов для извлечения следующих N различных значений. Возможно, N сначала может быть небольшим, а затем немного увеличиться, если пользователь хочет сидеть и ждать. С индексом SQL Server должен иметь возможность эффективно выполнять это.

Из книг MSDN онлайн:

Ограничивает строки, возвращаемые в результате запроса до заданного числа строк или процент строк в SQL Server 2014. Когда TOP используется в сочетании с ORDER BY, результирующий набор ограничивается первым номером упорядоченных строк ; в противном случае он возвращает первое число N строк в неопределенном порядке. Используйте этот раздел, чтобы указать число строк, возвращаемых из инструкции SELECT, или указать их в операторе INSERT, UPDATE, MERGE или DELETE в .

Есть и другие способы. Если вы хотите использовать N самых разных критериев, вы можете использовать один из ranking functions, например ROW_NUMBER, RANK, DENSE_RANK, или NTILE.

+0

Скопировано из приведенного выше комментария, надейтесь, что это имеет смысл: если я ВЫБИРАЮ ТОЛЬКО 50 DISTINCT Name FROM TABLE, возможно, придется пройти 10 000 000 записей, которые занимают 3 часа. Если я сделаю SELECT a.Name FROM (SELECT TOP 10000 * FROM TABLE). Поскольку это не займет столько времени и будет достаточно точным. –

+0

Теперь ROW_NUMBER может быть полезным направлением. На этом я мог бы сдерживать. Благодарю. –

+0

Задача с функциями ранжирования состоит в том, что вам все равно нужно получить доступ ко всей таблице, чтобы создать сегменты, прежде чем вы сможете их фильтровать. – billinkc

5

Если запрос прост, только с 1 таблицы в предложении FROM, вы можете просто изменить SELECT <columns> к SELECT TOP 100 <columns> (примечание: не если это DISTINCT).


Если запрос является более сложным, с несколькими таблицами и/или одной таблицы ссылаются несколько раз, вы можете изменить один из появления таблицы вы хотите ограничить, т.е.изменение:

SELECT ... 
FROM ...     -- some tables 
    <table_name> AS x 
    ...      -- some more joins 
WHERE ... 
... ; 

к:

SELECT ... 
FROM ...     -- some tables 
    (SELECT TOP 100 * 
    FROM <table_name> 
    ORDER BY <some_columns>  -- without ORDER BY if you don't care 
           -- which 100 rows will be checked 
    ) AS x 
    ...      -- some more joins 
WHERE ... 
... ; 

Другой подход, который будет работать с простой случай (имеет ли он DISTINCT или нет), и, если запрос является более сложным, с таблицей многократные ссылки и вы хотите ограничить все вхождения этой таблицы:

WITH table_name AS 
    (SELECT TOP 100 * 
    FROM <table_name> 
    ORDER BY <some_columns>  -- without ORDER BY if you don't care 
           -- which 100 rows will be checked 
    ) 
SELECT ... 
--- your query unchanged ; 
+0

Спасибо. В ожидании увидеть, отвечает ли @Lamak, так как он впервые предложил это решение в комментариях. –

+3

@ScottBeeson Не волнуйся, на самом деле не собирался отвечать, и я не мог опубликовать такой полный ответ, как этот. – Lamak