sql-server-2012 - SQL Server 选择查询需要很长时间才能使用 WHERE 子句执行
问题描述
我有一张表Table1
,其中包含 1 - 150 万行带有主键的行。
这是我的表结构
CREATE TABLE [dbo].[Table1]
(
[Id] [INT] NOT NULL,
[allow_public] [BIT] NULL,
[average_frequency] [DECIMAL](18, 4) NULL,
[category_id] [INT] NULL,
-- a few more columns
--
--
--
[member_id] [INT] NULL
CONSTRAINT [PK_Table1_Id]
PRIMARY KEY CLUSTERED ([Id] ASC)
)
像这样添加了一个非聚集索引member_id
:
CREATE NONCLUSTERED INDEX non_cluster_index_member_table1
ON dbo.Table1 (member_id)
WHERE member_id IS NOT NULL;
GO
当我执行查询时
SELECT
[id],
[accurate_grams],
[allow_public],
[average_frequency],
[category_id]
FROM
dbo.Table1
WHERE
member_id = @memberid;
它在几毫秒内返回一些行。但是当我执行类似的查询时
SET @OrgMemberId = ISNULL(@OrgMemberId, -1);
SELECT
[id],
[accurate_grams],
[allow_public],
[average_frequency],
[category_id]
FROM
dbo.Table1 f
WHERE
ISNULL(f.member_id, -1) = CASE
WHEN @MemberId = -1
THEN ISNULL(f.member_id, -1)
ELSE @MemberId
END
完成执行需要很多时间。
注意:member_id
列包含空值。并且它没有被映射为外键
ISNULL(f.member_id, -1) = CASE
WHEN @MemberId = -1
THEN ISNULL(f.member_id, -1)
ELSE @MemberId
END
写上一行的原因是 - 有时用户将空值发送到@MemberId
. 为了处理这种情况,我在 where 子句中使用了这一行。在单个查询中,我可以获取两个不同的结果。member_id is null
然后查询时选择所有记录,然后查询时仅member_id is not null
选择与Member_id
. 所以没有必要使用if else
.
有没有其他解决方案来处理这个问题?
解决方案
一种可能的方法是使用覆盖索引 - 一个包含查询需要返回的所有列的索引:
CREATE NONCLUSTERED INDEX ncix_table1_member_id
ON dbo.Table1 (member_id)
INCLUDE (id, accurate_grams, allow_public, average_frequency, category_id)
WHERE member_id IS NOT NULL;
GO
使用这种方法,现在只需查看索引就可以“满足”您的查询 - 它不必对实际表的数据页进行大量(相当昂贵的)“键查找”来获取“缺失”查询的列值
推荐阅读
- flutter - Flutter Text Overflow Animation 让全文可见
- http - http cookie 来自哪里,不是由“Set-Cookie”响应标头设置的?
- javascript - javascript clearInterval() function is not working
- c# - C#中windows子文件夹的访问被拒绝
- react-native - 在本机反应中使用反应导航的问题(出现未定义的错误)
- c - 使用 fgetc 获取 C 中的行数
- intellij-idea - Clojure 中的循环/返回。什么是“尾巴”位置?
- google-drive-api - Google Drive 选择器登录/加载问题
- gcc - 使用 Clang + LLD (MSys2/MingW) 链接简单的 C 程序会生成错误的展开表样式(.eh_frame 而不是.pdata)
- python - Scrapy-无法从 h3 中提取数据