【问题标题】:Which of the following query is optimised/preferred以下哪个查询是优化/首选的
【发布时间】:2017-01-11 10:35:19
【问题描述】:

考虑两个表 表A和表B

表A

|id|driver_id|vehicle_id|is_allowed|license_number|driver_name|

表B

|id|driver_id|vehicle_id|offence|payable_amount|driver_name|

目标:找到名称为 XYZ 的允许司机的 driver_id 和 vehicle_id。

Query1:SELECT * FROM tableA,tableB {join-condition}{filter-condition}

SELECT tableA.driver_id,tableA.vehicle_id FROM tableA,tableB 
WHERE
tableA.driver_id=tableB.driver_id AND 
tableA.vehicle_id=tableB.vehicle_id AND
tableA.driver_name='XYZ' AND
tableB.driver_name='XYZ' AND
tableA.is_allowed = 1

Query2:SELECT * FROM (SELECT * FROM tableA {filter-condition}) JOIN (SELECT * FROM tableB {filter-condition}) ON {join-condition}{filter-condition}

SELECT tableAA.driver_id,tableAA.vehicle_id FROM 
(SELECT tableA.driver_id,tableA.vehicle_id from tableA WHERE tableA.driver_name='XYZ' AND
tableA.is_allowed = 1) as tableAA,
JOIN
(SELECT tableB.driver_id,tableB.vehicle_id from tableB WHERE tableB.driver_name='XYZ') as tableBB
ON
tableAA.driver_id=tableBB.driver_id AND 
tableAA.vehicle_id=tableBB.vehicle_id

哪种类型的查询是可读、优化和符合标准的。

【问题讨论】:

  • 始终使用显式 JOIN 语法。第一个查询只是超级旧的遗留代码
  • 不应该tableA.driver_id=tableB.driver_id 暗示tableA.driver_name=tableB.driver_name
  • 我删除了不兼容的数据库标签。请为您真正使用的数据库添加标签。
  • @redneb,可能是也可能不是,因为两个值都可以由用户编辑,所以两个表可能有不同的名称。

标签: mysql sql database


【解决方案1】:

第一个在标准和性能方面更好,但非常老式,所以可以这样写

SELECT tableA.driver_id,tableA.vehicle_id 
FROM tableA
INNER JOIN tableB ON tableA.driver_id=tableB.driver_id 
    AND tableA.vehicle_id=tableB.vehicle_id 
    AND tableA.driver_name='XYZ' 
    AND tableB.driver_name='XYZ' 
    AND tableA.is_allowed = 1

【讨论】:

    【解决方案2】:

    正确的版本应该是这样的:

    SELECT a.driver_id, a.vehicle_id
    FROM tableA a JOIN
         tableB b
         ON a.driver_id = b.driver_id AND 
            a.vehicle_id = b.vehicle_id
    WHERE a.driver_name = 'XYZ' AND
          b.driver_name = 'XYZ' AND
          a.is_allowed = 1;
    

    注意事项:

    • JOIN 被认为是在 FROM 子句中组合表的正确方法。简单规则:切勿FROM 子句中使用逗号。
    • ON 子句应包含包含多个表中的列的所有谓词。
    • 使用表别名是一种偏好,它使查询更易于编写和阅读。
    • 您可能想要使用INEXISTS,因为您的查询没有返回来自TableB 的列。
    • 不要在FROM 子句中使用不必要的子查询。在某些数据库(尤其是 MySQL)中,这会阻碍索引的使用,并为中间表的具体化增加额外的开销。

    而且,您的问题的答案是第一个版本可能是优化版本(因为它不会不必要地实现子查询)。这两个版本都不是首选。

    【讨论】:

    猜你喜欢
    • 2021-05-04
    • 2013-12-15
    • 2012-08-21
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多