从表中获取随机行 - 尝试优化查询 - SQL Server

时间:2011-10-22 23:20:21

标签: .net sql sql-server

我需要从表中随机排。起初,我写了这样的SP:

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。

那么,采用随机行或优化查询的方法是否更多?

很多回复。

1 个答案:

答案 0 :(得分:1)

表中有多少行,是否可以修改架构?一个问题是所有选择都基于LEN(列),因此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