2011-10-22 49 views
0

我需要從表中隨機選擇一行。起初,我寫了SP這樣的:從表中獲取隨機行 - 嘗試優化查詢 - SQL Server

SELECT * FROM 
    (SELECT TOP 1 
    * 
    FROM PeopleTales PT 
    LEFT JOIN PeopleTalesCategories PTC ON PT.CategoryAn = PTC.Analit 
    WHERE LEN(PT.Text) > 900 
    ORDER BY NEWID() 
    ) t1 

這不是很好的實時統計:

平均總執行時間= 200

接下來,我試圖手動採取行:

WITH CTE_t 
AS 
(
     SELECT 
     ROW_NUMBER() OVER (ORDER BY PT.Analit) AS RowNumber, 
     * 
     FROM PeopleTales PT 
     LEFT JOIN PeopleTalesCategories PTC ON PT.CategoryAn = PTC.Analit 
     WHERE LEN(PT.Text) > 900 
) 


SELECT * FROM CTE_t 
WHERE CTE_t.RowNumber = 1 + ABS(CHECKSUM(NewId())) % (SELECT COUNT(CTE_t.RowNumber) FROM CTE_t) 

這是由執行時間好一點,但有時我有0行,有時結果1,2甚至3行! +我知道,使用CTE並不是很好。這不是決定。

平均總執行時間= 60

所以,下一步:

SELECT * FROM (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY PT.Analit) AS RowNumber, 
     * 
    FROM PeopleTales PT 
    LEFT JOIN PeopleTalesCategories PTC ON PT.CategoryAn = PTC.Analit 
    WHERE LEN(PT.Text) > 900 
    ) t1 
WHERE t1.RowNumber = (SELECT 1 + ABS(CHECKSUM(NewId())) % (SELECT 
                  COUNT(Analit) 
                  FROM PeopleTales 
                  WHERE LEN(Text) > 900)) 

每次我只有一個排,及其與總執行時間確定。

平均總執行時間= 60

那麼,是不是更多的方式來採取隨機行或優化我的查詢?

Thx很多的迴應。

回答

1

表中有多少行,是否可以修改您的模式?一個問題是所有的選擇都基於LEN(Column),所以SQL Server不能有效地使用索引。

你可能想要考慮的是一個計算列,並在其上放置一個索引。喜歡的東西:

ALTER TABLE PeopleTales ADD TextLength AS LEN(PT.Text) 
GO 
CREATE INDEX IX_PeopleTales_TextLen ON PeopleTales (Text, CategoryAN) 
GO 

我包括CategoryAN所以有聯接由索引純粹達成(並意味着SQL Server不具備做一個書籤或鍵查找)。

然後,顯然,更改您的查詢,以便WHERE LEN(PT.Text) > 900變成WHERE TextLength > 900

+0

1.有2000行,是的 - 我可以修改架構。是的,它有助於將平均執行時間降低到45-50。但是,MB在查詢中出現錯誤/不正確的地方,有什麼可以重寫的? – FSou1

+0

你的執行計劃是什麼樣的?這應該是您的第一個停靠港,因爲它會顯示花費時間。另外,您的目標查詢時間是多少? –