更新:对于读这篇文章的人来说,正如@dnoeth所述,索引在查询时间方面有很大的不同。在某些情况下,它会将行扫描减少到1行。您只需要选择最适合您的索引风格。 Clustered vs Non Clustered
索引示例:
E.g: create index ix_descr on my_db.media (description asc)
我有一个需要很长时间才能运行的查询,它在where子句中有很多功能。优化查询的最佳方法是什么?
将函数移出where子句并用连接等替换它们?
我在下面给出了一些简单的例子,图2 和 3 是我的最佳尝试,让我知道你的想法。
注意*这些不是我正在使用的实际功能,我使用dbo.DecryptBlob(m.mediaId)等。我选择使用下面的函数来使问题更容易掌握。
图1。)
SELECT
description, id
FROM
my_db.media
where
length(description) = 10
and description like "S%"
and trim(left(m.description,2)) = 'St'
可能的优化
图2。)(使用加入和分组)
SELECT
m.description, m.mediaId
FROM
my_db.media m
inner JOIN
my_db.media m1 ON length(m.description) = 10
and m.description like "S%"
and trim(left(m.description,2)) = 'St'
group by m.mediaId
图3。)(使用join和distinct)
SELECT distinct
m.description, m.mediaId
FROM
my_db.media m
inner JOIN
my_db.media m1 ON length(m.description) = 10
and m.description like "S%"
and trim(left(m.description,2)) = 'St'
答案 0 :(得分:0)
您的开始评论我的短语为"请勿隐藏功能内的索引列,优化工具无法找到它以使用INDEX
。"
and description like "S%"
and trim(left(m.description,2)) = 'St'
与
相同and description LIKE "St%"
有了它,INDEX(description)
将很好地工作。检查长度= 10是次要的,而不是真正的问题。它会做一个"范围"扫描该指数。 (如果您不是指' 2' St',那么我的评论可能不会适用。)
TRIM
- 清除输入,而不是在SELECT
期间尝试清除输入。
在这种情况下,使用JOIN
会显示事情。
这是错误的"在group by m.mediaId
列表中未指定mediaId
的情况下执行SELECT
。所以,我不知道你在图2中的目标。
答案 1 :(得分:0)
如果您的应用程序经常选择描述的长度,您应该考虑添加一个包含描述长度的列并在其上创建索引。