SQL WHERE子句优化

时间:2014-08-18 14:33:14

标签: sql optimization

假设我有以下三种类型:

  • 类型1
  • 2型
  • 的Type3

从优化的角度来看(忽略可维护性;我知道如果添加新类型,第一个选项不太可能中断);写这样的where子句会更有效率:

WHERE p.TypeId IN (Type1, Type2)

WHERE p.TypeId <> Type3

2 个答案:

答案 0 :(得分:0)

您的第二个选择:

WHERE p.TypeId <> Type3

编写效率会更高,因为它使用更少的字符,除非你在iPad上,在这种情况下,到达&lt;和&gt;字符!

在执行方面,执行起来也会更快。显然,由于只需要进行一次比较,因此工作量较少,因此无论您采用哪种方式进行优化,都可以进行优化。有两个元素将比IN更快。

答案 1 :(得分:0)

这可能取决于索引的配置方式以及表中的数据,但对于简单的测试用例,可以证明它们可以在SQL Server 2005中创建相同的查询计划。

以下代码在SQL Server 2005实例上运行,为查询的OR,IN和不等版本生成了相同的查询计划。每个查询产生相同数量的记录。第一组查询使用3值相等分布。第二组查询使用10值相等的分布。

CREATE TABLE #Test (TestID int, TestTypeID int);

WITH TallyTable AS
(
    SELECT
    TOP 10000
    ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Tally
    FROM            sys.objects s1
    CROSS JOIN      sys.objects s2
), InsertList AS
(
    SELECT
        Tally AS TestID,
        Tally % 3 AS TestTypeID
    FROM    TallyTable
)
INSERT INTO #Test
    (
        TestID,
        TestTypeID
    )
SELECT
    TestID,
    TestTypeID
FROM        InsertList;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

CREATE INDEX TestIndex ON #Test (TestTypeID);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

DROP INDEX TestIndex ON #Test;

TRUNCATE TABLE #Test;

WITH TallyTable AS
(
    SELECT
    TOP 10000
    ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Tally
    FROM            sys.objects s1
    CROSS JOIN      sys.objects s2
), InsertList AS
(
    SELECT
        Tally AS TestID,
        Tally % 10 AS TestTypeID
    FROM    TallyTable
)
INSERT INTO #Test
    (
        TestID,
        TestTypeID
    )
SELECT
    TestID,
    TestTypeID
FROM        InsertList;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2
OR          TestTypeID = 3
OR          TestTypeID = 4
OR          TestTypeID = 5
OR          TestTypeID = 6
OR          TestTypeID = 7
OR          TestTypeID = 8
OR          TestTypeID = 9;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2,3,4,5,6,7,8,9);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

CREATE INDEX TestIndex ON #Test (TestTypeID);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2
OR          TestTypeID = 3
OR          TestTypeID = 4
OR          TestTypeID = 5
OR          TestTypeID = 6
OR          TestTypeID = 7
OR          TestTypeID = 8
OR          TestTypeID = 9;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2,3,4,5,6,7,8,9);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

DROP TABLE #Test;

此集使用3值不等分布,并且还会生成相同的查询计划。

CREATE TABLE #Test (TestID int, TestTypeID int);

WITH TallyTable AS
(
    SELECT
    TOP 10000
    ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Tally
    FROM            sys.objects s1
    CROSS JOIN      sys.objects s2
), InsertList AS
(
    SELECT
        Tally AS TestID,
        CASE
            WHEN Tally % 1000 = 0 THEN 2
            WHEN Tally % 100 = 1 THEN 1
            ELSE 0
        END AS TestTypeID
    FROM    TallyTable
)
INSERT INTO #Test
    (
        TestID,
        TestTypeID
    )
SELECT
    TestID,
    TestTypeID
FROM        InsertList;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

CREATE INDEX TestIndex ON #Test (TestTypeID);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID = 0
OR          TestTypeID = 2;

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID IN (0,2);

SELECT
    TestTypeID
FROM        #Test
WHERE       TestTypeID <> 1;

DROP TABLE #Test;