我试图将此查询转换为更多SARGable(主要是LEN(CardNumber .....)位)的任何想法? (这只是查询的一部分)。 CardNumber
为Varchar(50)
且已有index
SELECT ContactGUID, CardNumber,
ROW_NUMBER() OVER(PARTITION BY ContactGUID ORDER BY SignedDate DESC) as row_no
FROM Cards
WHERE CardNumber LIKE '633176%'
AND LEN(CardNumber) IN (16, 19) AND (Status IS NULL OR Status = 'A')
AND ContactGUID IS NOT NULL
非常感谢任何帮助/建议。
谢谢
答案 0 :(得分:2)
所以,如果您的索引正确,首先 - like '1234%'
速度很快。当然,这仅适用于CardNumber
不是nvarchar
/ nchar
/ ntext
等的情况 - 如果是,请改为使用like N'1234%'
。
len(CardNumber)
不是,但引擎应该足够聪明,首先评估like
。如果仍然留下太多匹配的行,那么你只需要有一个长度为CardNumber
的计算列,并在其上有一个索引。
另外,根据我的经验,over (partition by ..., order by ...)
往往很慢。
无论如何,您是否真的监控过性能问题?如果是这样,您可以检查执行计划以查看问题所在。
答案 1 :(得分:0)
您是否尝试在LIKE
中使用“_”(单个字符的通配符)。
例如:
...
AND (CardNumber LIKE '633176__________'
OR CardNumber LIKE '633176___________'
OR CardNumber LIKE '633176____________'
OR CardNumber LIKE '633176_____________')
...
虽然,我不确定它实际上会更快。
答案 2 :(得分:0)
问题当然在于len(cardNumber)
您可以尝试(Cross应用T-sql的功能)
以下是关于此主题的好文章的链接: http://weblogs.sqlteam.com/jeffs/archive/2007/10/18/sql-server-cross-apply.aspx