2

We have Fact table around 35M rows on Azure database (premium tier), this table has cluster columnstore index enabled in order to boost query performance.

We did pagination (to index on Elastic Search) on Fact table using similar below code:

SELECT *
FROM [SPENDBY].[FactInvoiceDetail]
ORder by id
offset 1000000 rows fetch next 1000 rows only

But this query performs so slow, even over 10 minutes, it's not finished. If we change to use TOP, it works really well and take around 30 seconds:

SELECT TOP 1000 * 
FROM [SPENDBY].[FactInvoiceDetail]
WHERE ID > 1000000 
ORDER BY Id

The estimated execution plan for offset-fetch query:

enter image description here

I am not sure that I understand whether offset-fetch query performs very poorly on cluster columnstore index or not.

This table also have a lot of none-cluster B-tree indexes on foreign keys and one unique index on the Id of Fact table in order to boost performance

This execution plan for offset-fetch query:

https://pastebin.com/BM8MXQMg

4

3 に答える 3

1

ここでの主な問題は、OFFSET の値が大きいことです。

オフセット 1000000 行 次の 1000 行のみをフェッチ

OFFSET 値が小さい場合、OFFSet と Fetch はうまく機能します。詳細については、以下の例を参照してください。

SELECT orderid, orderdate, custid, filler
FROM dbo.Orders
ORDER BY orderdate DESC, orderid DESC
OFFSET 50 ROWS FETCH NEXT 10 ROWS ONLY;

キー列とselectの列が含まれているため、列ごとに並べ替えています..これにより、計画の下になります..

ここで注目すべき重要な点は、SQLServer が Offset+fetch (50+10) 行を読み取り、最後に 10 行をフィルタリングすることです。

ここに画像の説明を入力

したがって、大きなオフセットを使用すると、適切なインデックスを使用しても、1000000 + 1000 行の読み取りで終了します。これは非常に巨大です。

スキャンの直後にSQLサーバーに1000行を除外するように依頼できる場合、それはクエリを助けることができます..これ(スキーマでテストされていません)、クエリを次のように書き直すことで実現できます

WITH CLKeys AS
(
 SELECT ID
 FROM yourtable
 ORDER BY ID desc
OFFSET 500000 ROWS FETCH FIRST 10 ROWS ONLY
)
SELECT K.*, O.rest of columns 
FROM CLKeys AS K
CROSS APPLY (SELECT columns needed other than id
FROM yourtable  AS A
WHERE A.id= K.id) AS O
ORDER BY Id desc;

参照:
http://sqlmag.com/t-sql/offsetfetch-part-1#comment-25061

于 2017-05-09T15:33:40.133 に答える