好还是坏&;为什么要在SQL查询连接中应用复杂查询?

好还是坏&;为什么要在SQL查询连接中应用复杂查询?,sql,Sql,更新日期:2020-09-14 我正在写一个类似这样的问题 SELECT T1.*,T2.* FROM T1 LEFT OUTER JOIN (A complex query which traverse entire table & returning a very big dataset) T2 ON T2.T1ID = T1.ID 在T2.T1ID=T1.ID之后,它返回一个小数据集 这个问题的主要原因是当删除括号并将查询合并到一个括号中时,可以对其进行优化 但这需

更新日期:2020-09-14

我正在写一个类似这样的问题

SELECT T1.*,T2.* 
FROM T1 
LEFT OUTER JOIN 
    (A complex query which traverse entire table & returning a very big dataset) T2 ON T2.T1ID = T1.ID
在T2.T1ID=T1.ID之后,它返回一个小数据集

这个问题的主要原因是当删除括号并将查询合并到一个括号中时,可以对其进行优化

但这需要付出努力,并且与T2查询的复杂程度成正比

问题是:

  • 对于带括号的原始查询,T2将首先执行(它执行并查询大数据集),然后与T1连接,这是真的吗

  • 如果是,是否仍要将筛选器T2.T1ID=T1.ID传递到括号中,以便它可以查询预期的小数据集,而不是整个表

  • 另外,SQL表被定义为简单的、初步的,并且在MSSQL server上没有任何索引/RDBMS处理

    对于“这对SQL性能有害”的最佳答案是尝试一下并查看解释。 几乎总是,真正的问题不是“如果我有很多行那么糟糕吗”,而是“查询优化器能否在连接和where子句上使用索引”

    由于您不共享DDL,或者实际上不共享RDBMS,因此很难在这个答案中定义

    答案在很大程度上取决于查询优化器的智能程度

    如果T1在ID上有一个索引,而TA和TB在T1ID上有一个索引,那么如果您只是在ID=T1ID上有
    外部连接TA
    外部连接TB=T1ID

    括号内的派生表是一个技巧,它可以让同一个查询查看具有相似列的两个不同表,具体取决于应用程序逻辑。如果查询优化器足够聪明,能够意识到这个派生表使用具有适当索引的表,那么您的查询应该尽可能快。但这对查询优化器来说要求很高——它不会事先知道@a的值是什么

    执行此操作的另一种方法(更有可能命中联接上的索引)是:

    SELECT T1.*,TA.* 
    FROM T1 
    LEFT OUTER JOIN TA on T1.id = TA.T1ID
    where @A = 1
    UNION ALL
    SELECT T1.*,TB.* 
    FROM T1 
    LEFT OUTER JOIN TB on T1.id = TB.T1ID
    where @A = 0
    

    尽管如此,如果没有模式或RDBMS,这是不可能确定的。

    我认为您编写查询的方式不是一个好主意。特别是,优化器可能会丢失有关这两个表的统计信息和索引的信息

    我建议将代码编写为:

    SELECT T1.*, COALESCE(TA.VAL, TB.Val) as val
    FROM T1 LEFT JOIN 
         TA 
         ON TA.T1ID = T1.ID AND @A = 1 LEFT JOIN
         TB 
         ON TB.T1ID = T1.ID AND @A = 0; 
    

    这只是一个从TA或TB中选择的技巧。如果@A=x为false,则无论大小都不会有任何行返回。如果@A=1,我假设查询优化器将检测到TB的where子句始终为false,甚至不会触及TB。SQL表被定义为简单的、初步的,在ms SQL上没有任何索引/rdbms处理server@SKLTFZ-请更新用这些信息提问。添加索引将比更改查询本身产生更大的影响!