我需要从表中随机排。起初,我写了这样的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。
那么,采用随机行或优化查询的方法是否更多?
很多回复。
答案 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
。