Sql 调整昂贵的查询

Sql 调整昂贵的查询,sql,performance,Sql,Performance,我有一个问题: SELECT MIN(Numero) FROM view_OperatoriCpuLiberi WHERE IDCpu = '9e2da792-be47-e311-aea8-b4b52fb677e0' AND Numero > 100 AND IDGruppo IN ( SELECT AssociazioniCampo.IDOggetto AS IDGruppiAutorizzati FROM Anag.ListeAssociazioni

我有一个问题:

SELECT MIN(Numero) 
FROM view_OperatoriCpuLiberi 
WHERE IDCpu = '9e2da792-be47-e311-aea8-b4b52fb677e0' 
AND Numero > 100 AND IDGruppo IN 
(
    SELECT AssociazioniCampo.IDOggetto AS IDGruppiAutorizzati 
    FROM Anag.ListeAssociazioni 
    INNER JOIN Anag.AssociazioniCampo ON ListeAssociazioni.IDLista = AssociazioniCampo.IDLista 
    INNER JOIN Campo.Oggetti ON AssociazioniCampo.IDOggetto = Oggetti.IDOggetto 
    WHERE ListeAssociazioni.IDTipoMacroOggetto = 5 
    AND ListeAssociazioni.IDTipoAssociatoCampo = 74 
    AND Deleted = 0 
    AND IDMacroOggetto = 'c3f2c542-a195-11e0-a2e3-000c2962b9f0'
)

“view_OperatoriCpuLiberi”包含81981行,嵌套查询(括号之间)包含861行。查询耗时超过2秒。如果我删除嵌套查询,然后删除“IDGruppo IN”指令,它会变得非常快。我能做什么?

我可能会这样写这个查询,尽管它是否性能更好可能取决于事物的索引方式等

你没有在你所有的专栏上使用别名,所以我不得不猜测其中一些是从哪里来的

SELECT
    MIN(OCL.Numero) 
FROM
    view_OperatoriCpuLiberi OCL -- Ugh. Object name prefixes are evil.
INNER JOIN Anag.AssociazioniCampo AC ON
    AC.IDOggetto = OCL.IDGruppo
INNER JOIN Anag.ListeAssociazioni LA ON
    LA.IDLista = AC.IDLista AND
    LA.IDTipoMacroOggetto = 5 AND
    LA.IDTipoAssociatoCampo = 74 AND
    LA.Deleted = 0 AND
    LA.IDMacroOggetto = 'c3f2c542-a195-11e0-a2e3-000c2962b9f0'
INNER JOIN Campo.Oggetti O ON O.IDOggetto = AC.IDOggetto
WHERE
    OCL.IDCpu = '9e2da792-be47-e311-aea8-b4b52fb677e0' AND
    OCL.Numero > 100 AND

表之间的所有外键至少应有索引。

您使用的是什么数据库?您可以发布表结构和表上的任何索引吗?谢谢。我看不出有任何理由必须是次选择。它可以被重新编写为一个简单的连接…是的,我觉得这取决于您的数据库,但我似乎记得,较旧版本的SQL在Where子句中对子查询的性能造成了相当大的影响。根据Marc B的建议,尝试将子查询移动到FROM子句中,然后将其联接。它是SQL Server 2008R2,好的,我尝试将其转换为普通联接查询并提供反馈。除了表结构和索引之外,在请求性能帮助时为查询包含查询计划通常也是一个好主意。回答得好。只是好奇,为什么你认为对象名称前缀邪恶?您的意思是将存储过程命名为“usp\u GetCustomerList”,或者在本例中,将视图命名为“view\u myAwesomeView”。。。最后一个有点多余,但你明白了。你应该知道对象已经是一个视图了,当视图必须变成一个表(反之亦然)时,你该怎么办。我曾经遇到过这样的情况:一个表(tblWhatever)被一个跨分区的视图替换。现在这个名字不再准确了。也许你可以重构它,但那可能很难。此外,我还是可读性强、阅读自然的代码的大力支持者。将类型前缀添加到所有对象会影响这一点。最后,“邪恶”是夸张的,但我认为你从中几乎得不到任何东西,但可能会损失很多。重构肯定会导致一些问题。