我对mssql 2008有一个看法.T-SQL代码如下所示,
SELECT *
FROM View1
WHERE Category = 1
UNION ALL
SELECT *
FROM View1 AS Level#1
WHERE Category = 2 AND NOT EXISTS
(SELECT *
FROM View1
WHERE Level#1.Code = Code AND CategoryCode = 1)
P.S。代码; 代码的dataype是nvarchar - View1是相同的视图
当我从大约3500条记录中执行此代码时,结果将超过5分钟。
如何修改此代码以快速执行? 现在谢谢你的建议。
答案 0 :(得分:1)
您的问题(包含给定信息)是一个视图和SELECT *
视图只是一个扩展到原始表的宏。因此,如果视图有4个表,那么您的UNION现在具有相同的4个表,每个表使用次数
SELECT *
也意味着索引将无法有效使用(如果有的话)。您将在执行计划中获得扫描或密钥查找,因为您无法使用覆盖索引等
如果您的视图位于单个表上,那么它可能会被抢救,但您也可以使用临时表来执行此操作。
答案 1 :(得分:0)
不知道你的表/索引定义是什么,所以我可能错了,但这个代码乍一看似乎没必要:
AND NOT EXISTS
(SELECT *
FROM View1
WHERE Level#1.Code = Code AND CategoryCode = 1)
因为WHERE Category = 2
UNION ALL
答案 2 :(得分:0)
如果您使用的是SQL Server 2005或更高版本,可以尝试以下方法:
WITH ranked AS (
SELECT
*,
rnk = RANK() OVER (PARTITION BY Code ORDER BY Category)
FROM View1
WHERE Category IN (1, 2)
)
SELECT
* /* this will include the 'rnk' column too;
in any event, masked output is a very
discouraged thing to do so you should
probably specify the columns explicitly */
FROM ranked
WHERE rnk = 1
如果每个Code
永远不会有多个Category
,请将RANK()
替换为ROW_NUMBER()
,这应该更有效。
有用的阅读:
答案 3 :(得分:0)
不是100%确定我理解您的查询,但请尝试这一点,看看您是否得到了相同的(预期)结果:
SELECT *
FROM View1
WHERE Category = 1
UNION ALL
SELECT *
FROM View1 AS Level#1
LEFT JOIN View1 as XX ON Level#1.code=XX.Code and XX.CategoryCode =1
WHERE Level#1.Category = 2 AND xx.code is NULL