Sql 选择案例绩效

Sql 选择案例绩效,sql,sql-server,database,rdbms,Sql,Sql Server,Database,Rdbms,假设我们有这个表: |------------------------------| | col | data type | |------------------------------| | id | bigint | | first_name | nvarchar | | last_name | nvarchar | | photo | binary | |-------

假设我们有这个表:

|------------------------------|
| col           | data type    | 
|------------------------------|
| id            | bigint       |
| first_name    | nvarchar     |
| last_name     | nvarchar     |
| photo         | binary       |
|------------------------------|
好的,现在我们需要对该表进行两个查询:

|------------------------------|
| col           | data type    | 
|------------------------------|
| id            | bigint       |
| first_name    | nvarchar     |
| last_name     | nvarchar     |
| photo         | binary       |
|------------------------------|
  • 列出不带照片列的所有表行(加载为空)
  • 使用照片列加载特定行
为此,我们希望使用SP

第一种方法如下:

SELECT Top 50
    id,
    first_name,
    last_name,
    CASE WHEN @id IS NULL THEN null ELSE photo END as photo
FROM MyTable
WHERE @id IS NULL OR id=@id
SELECT 
    id,
    first_name,
    last_name,
    photo
FROM MyTable
WHERE id=COALESCE(@id,id)
第二种方法是:

IF (@id IS NULL)
    SELECT Top 50
        id,
        first_name,
        last_name,
        null as photo
    FROM MyTable
ELSE
    SELECT 
        id,
        first_name,
        last_name,
        photo
    FROM MyTable
    WHERE id=@id
END
第二种方法显然是一次性检查if条件并完成工作

但我喜欢编写类似SPs的第一种方法,我不知道sql server是否会在@id为NULL时检查每行的
大小写,或者查询优化器是否会在没有
大小写的情况下优化查询

编辑1:


我想知道第一个查询是否总是在没有大小写的情况下执行?因为它正在检查一个不改变值且与任何列值都不相关的变量。

您可以尝试这样做,这样可以避免出现
情况以及
IF
。不过,我承认这有点神秘

SELECT Top 50
       id,
       first_name,
       last_name,
       null as photo
FROM   MyTable
WHERE  @id IS NULL
UNION ALL
SELECT id,
       first_name,
       last_name,
       photo
FROM   MyTable
WHERE  id = @id

您可以尝试这样做,这样可以避免出现
案例
,也可以避免出现
IF
。不过,我承认这有点神秘

SELECT Top 50
       id,
       first_name,
       last_name,
       null as photo
FROM   MyTable
WHERE  @id IS NULL
UNION ALL
SELECT id,
       first_name,
       last_name,
       photo
FROM   MyTable
WHERE  id = @id

执行此操作的标准方法(将null参数默认值设为all)如下所示:

SELECT Top 50
    id,
    first_name,
    last_name,
    CASE WHEN @id IS NULL THEN null ELSE photo END as photo
FROM MyTable
WHERE @id IS NULL OR id=@id
SELECT 
    id,
    first_name,
    last_name,
    photo
FROM MyTable
WHERE id=COALESCE(@id,id)

根据我的经验,如果ID上有索引,那么这在所有主要平台上都能提供良好的性能。执行此操作的标准方法(将null参数默认值设置为all)如下所示:

SELECT Top 50
    id,
    first_name,
    last_name,
    CASE WHEN @id IS NULL THEN null ELSE photo END as photo
FROM MyTable
WHERE @id IS NULL OR id=@id
SELECT 
    id,
    first_name,
    last_name,
    photo
FROM MyTable
WHERE id=COALESCE(@id,id)

根据我的经验,如果ID上有一个索引,那么它在所有主要平台上都有很好的性能。因为有些答案已经发布了,所以我决定亲自检查一下

SQL Server 2014上的安装程序 执行时间:13秒

执行计划:

查询#2-ELSE子句中OP的查询: 执行时间:0秒

执行计划:

查询#3-@Ann的查询: 执行时间:0秒

执行计划:

查询#4-@霍根的查询: 执行时间:14秒

执行计划:

结论 对于
@id
有值的情况,您和Hogan在单个查询中统一逻辑的尝试都不如单独进行查询。在这两种情况下,您都可以看到查询实际上是扫描整个聚集索引,而不是执行更直接的索引查找

有趣的是,尽管Ann的执行计划似乎是所有计划中最复杂的,但性能表明优化器不知何故能够检测到
@id
不是空的,并在这种情况下缩短了昂贵的集群索引扫描


尽管如此,由于您已经在存储过程中,在我看来,您应该坚持使用
if-else
方法。这似乎是最安全的方法。

因为有些答案已经贴出来了,我决定自己去看看

SQL Server 2014上的安装程序 执行时间:13秒

执行计划:

查询#2-ELSE子句中OP的查询: 执行时间:0秒

执行计划:

查询#3-@Ann的查询: 执行时间:0秒

执行计划:

查询#4-@霍根的查询: 执行时间:14秒

执行计划:

结论 对于
@id
有值的情况,您和Hogan在单个查询中统一逻辑的尝试都不如单独进行查询。在这两种情况下,您都可以看到查询实际上是扫描整个聚集索引,而不是执行更直接的索引查找

有趣的是,尽管Ann的执行计划似乎是所有计划中最复杂的,但性能表明优化器不知何故能够检测到
@id
不是空的,并在这种情况下缩短了昂贵的集群索引扫描


尽管如此,由于您已经在存储过程中,在我看来,您应该坚持使用
if-else
方法。这似乎是最安全的方法。

检查执行计划并进行比较。是的,你是对的,但我的问题是如何优化?这只是一个例子。thx@sstan示例中的执行计划不会回答您关于如何优化类似内容的问题吗?即使这只是一个例子,@sstan告诉我们的。但是根据我的经验,有两个独立的查询可能会有更好的性能。SQL Server或任何其他RDBMS都不喜欢
子句。我尝试了执行计划,但无法找到它。检查执行计划并进行比较。是的,你是对的,但我的问题是如何对其进行优化?这只是一个例子。thx@sstan示例中的执行计划不会回答您关于如何优化类似内容的问题吗?即使这只是一个例子,@sstan告诉我们的。但是根据我的经验,有两个独立的查询可能会有更好的性能。SQL Server或任何其他RDBMS都不太喜欢
子句。我尝试过执行计划,但无法理解。谢谢详细的回答谢谢详细的回答