首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何摆脱这些关键的查找?

如何摆脱这些关键的查找?
EN

Database Administration用户
提问于 2016-08-29 18:09:24
回答 3查看 178关注 0票数 0

我有一个疑问:

代码语言:javascript
复制
    SELECT TOP (20) table1.Vit_Codigo
    ,table1.Vit_Nome
    ,table1.Vit_Apelido
    ,table1.Vit_codigoStatus
    ,table1.Vit_Numero
    ,table1.Vit_Ano
    ,table1.Vit_CodigoTiposExames
    ,table3.Esp_Setor
    ,table2.TEs_Descricao
FROM table1
LEFT JOIN table2 ON tb_Vitima.Vit_CodigoTiposExames = table2.TEs_Codigo
LEFT JOIN table3 ON table3 .Esp_Codigo = table1.Vit_CodigoEspecialidade
WHERE (rtrim(ltrim(lower(tb_Vitima.Vit_Rg))) = 'n/a')
    AND (
        table1.Vit_codigoStatus IN (
            3
            ,4
            )
        )
ORDER BY table1.Vit_DataAberturaReal DESC

这些计划是:

我做了这个指数:

代码语言:javascript
复制
create index IX_SELECTTOP20_INCLUDE 
    on table1
    ( Vit_Rg ,Vit_codigoStatus )
include (
Vit_Codigo , Vit_Nome , Vit_Apelido , Vit_Numero ,
               Vit_Ano , Vit_CodigoTiposExames )

...but代码似乎使用的是旧的索引。

那么,为什么我的索引仍然使用键查找?

EN

回答 3

Database Administration用户

发布于 2016-08-29 20:03:15

这两种指数似乎都没有“涵盖”。为了避免关键查找,您必须至少INCLUDE SELECTWHEREORDER BY中涉及的每一列。

使用旧索引的原因是它对查询更好。这部分是因为Vit_DataAberturaReal上的索引阻止了计划中的排序操作符--因为数据已经正确地排序了。这也是因为新索引中的第一列在查询非粘合中毫无用处。如果您可以删除RTRIMLTRIMLOWER,那么性能可能会更好。

如果索引仅支持此查询,则可以考虑将WHERE Vit_codigoStatus IN (3,4)添加到索引定义中。

理想情况下,WHERE列应该是索引本身的一部分,而不是在INCLUDE中。如果我要专门创建一个索引来支持这个查询,那么它很可能是这样的:

代码语言:javascript
复制
CREATE INDEX [IX_SELECTTOP20_INCLUDE]
    ([Vit_DataAberturaReal])
INCLUDE(
    [Vit_Codigo], [Vit_Nome], [Vit_Apelido], [Vit_codigoStatus],
    [Vit_Numero], [Vit_Ano], [Vit_CodigoTiposExames],
    [Vit_CodigoEspecialidade], [Vit_Rg]) 
WHERE [Vit_Rg] = 'n\a' AND [Vit_codigoStatus] IN ( 3, 4 )

注意:这将不支持LTRIM(RTRIM(LOWER(...)))

票数 1
EN

Database Administration用户

发布于 2016-08-29 18:58:17

因为您的新索引没有

尝试在Vit_DataAberturaReal上不使用排序

排序的索引不包括select中的所有字段。

代码语言:javascript
复制
create index IX_SELECTTOP20_INCLUDE 
    on tb_vitima 
        ( Vit_Rg ,Vit_codigoStatus )
include ( Vit_Codigo,  Vit_Nome 
        , Vit_Apelido
        , Vit_Numero, Vit_Ano 
        , Vit_CodigoTiposExames )

SELECT TOP(20) tb_Vitima.Vit_Codigo,  tb_Vitima.Vit_Nome   
             , tb_Vitima.Vit_Apelido, tb_Vitima.Vit_codigoStatus 
             , tb_Vitima.Vit_Numero,  tb_Vitima.Vit_Ano 
             , tb_Vitima.Vit_CodigoTiposExames
             , lst_Especialidades.Esp_Setor, lst_TiposExames.TEs_Descricao 
FROM tb_Vitima 
LEFT OUTER JOIN lst_TiposExames 
     ON tb_Vitima.Vit_CodigoTiposExames = lst_TiposExames.TEs_Codigo 
    AND tb_Vitima.Vit_codigoStatus in(3, 4) 
LEFT OUTER JOIN lst_Especialidades 
     ON lst_Especialidades.Esp_Codigo = tb_Vitima.Vit_CodigoEspecialidade 
    AND rtrim(ltrim(lower(tb_Vitima.Vit_Rg))) = 'n/a'

order by tb_Vitima.Vit_DataAberturaReal desc
票数 0
EN

Database Administration用户

发布于 2016-08-30 11:44:38

哇,我刚刚从查询中取出了ltrim,现在正全速运行。正因为如此,查询现在使用paralelism:

但是,为什么会发生这种事?我真的很好奇

如果我关闭RTRIM,查询仍在缓慢运行。它只适用于LTRIM。

票数 -2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/148238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档