Я всегда проверяю, сколько данных я запрашиваю в запросе и пытаюсь устранить ненужные столбцы, а также строки. Ну, это только очевидные моменты, которые вы, возможно, уже проверяли, но просто хотели указать на случай, если вы еще этого не сделали. В вашем запросе низкая производительность может быть вызвана тем, что вы делаете «Выбрать *». Выбор всех столбцов из таблицы не позволяет прийти с хорошим планом выполнения. Проверьте, нужны ли только выбранные столбцы и убедитесь, что у вас есть правильный индекс покрытия в таблице Заказы.
Поскольку явная функция SKIPP или OFFSET недоступна в версии SQL 2008, нам нужно создать одно и что мы можем создать с помощью INNER JOIN. В одном запросе мы сначала сгенерируем идентификатор с OrderDate, и больше ничего не будет в этом запросе. Мы делаем то же самое во втором запросе, но здесь мы также выбираем некоторые другие заинтересованные столбцы из таблицы ORDER или ALL, если вам нужен ВСЕ столбец. Затем мы присоединяем это для запроса результатов по параметрам ID и OrderDate и ADD SKIPP для первого запроса, где набор данных имеет минимальный размер, что требуется. Попробуйте этот код.
SELECT q2.*
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNum, OrderDate
FROM Orders
WHERE OrderDate >= '1980-01-01'
)q1
INNER JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNum, *
FROM Orders
WHERE OrderDate >= '1980-01-01'
)q2
ON q1.RowNum=q2.RowNum AND q1.OrderDate=q2.OrderDate AND q1.rownum BETWEEN 30000 AND 30020
Чтобы дать вам оценку, я попытался это со следующими данными испытаний и независимо от того, какое окно вы запрашиваете результаты обратно менее чем за 2 секунд, и обратите внимание, что таблица КУЧА (нет индекса) Таблица содержит всего 2M строк.Тест выбора запрашивает 10 строк от 50000 до 50,010
Ниже Insert занимает около 8 минут.
IF object_id('TestSelect','u') IS NOT NULL
DROP TABLE TestSelect
GO
CREATE TABLE TestSelect
(
OrderDate DATETIME2(2)
)
GO
DECLARE @i bigint=1, @dt DATETIME2(2)='01/01/1700'
WHILE @I<=2000000
BEGIN
IF @i%15 = 0
SELECT @DT = DATEADD(DAY,1,@dt)
INSERT INTO dbo.TestSelect(OrderDate)
SELECT @dt
SELECT @[email protected]+1
END
Выбор окна 50 000 до 50,010 потребовалось менее 3 секунд.
Выбор последнего одной строки 2000000 до 2000000 также занял 3 секунды.
SELECT q2.*
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNum
,OrderDate
FROM TestSelect
WHERE OrderDate >= '1700-01-01'
)q1
INNER JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNum
,*
FROM TestSelect
WHERE OrderDate >= '1700-01-01'
)q2
ON q1.RowNum=q2.RowNum
AND q1.OrderDate=q2.OrderDate
AND q1.RowNum BETWEEN 50000 AND 50010
Покажите полный запрос, который вы используете, и предоставите 'CREATE TABLE', включая индексы для задействованных таблиц. –
@Peru, какова структура таблицы заказов? – Michael