mysql - MySQL 中的过滤行效率

标签 mysql sql-server join filter operator-precedence

我正在学习 SQL,其背景是科学编程(Matlab、Python)。操作顺序很大程度上决定了这些语言的计算效率,我想知道 SQL 是否也一样。我希望在学习 SQL 的同时尽早制定良好的编程策略,而不是稍后再对其进行改进。我的问题涉及效率。

场景: 我正在尝试使用另一个表 (report_data) 中的列中的信息来过滤一个表 (job_log_test) 中的行。这两个表具有相同的索引对应关系,每一行都属于一个单独的作业。我已经针对这个问题提出了两种可能不是最佳的解决方案:

解决方案 1: 首先将两个表中相关列的所有行连接在一起,然后根据源自 bill_customer 列中的值过滤行report_data 表。

SELECT xxx.job_number, xxx.customer_name 
FROM (
  SELECT job_number, customer_name, bill_customer 
      FROM job_log_test 
      INNER JOIN report_data 
      ON job_log_test.job_log_test_id = report_data.report_data_id
    )xxx 
WHERE bill_customer IS TRUE;

解决方案 2:report_data 运行子查询以生成要提取的行的索引列表。然后,使用该列表从 job_log_test 中提取所需的行。

SELECT job_number, customer_name 
FROM job_log_test 
WHERE job_log_test_id 
IN (
  SELECT report_data_id 
    FROM report_data 
    WHERE bill_customer IS TRUE
);

经验丰富的 SQL 程序员推荐以下哪种解决方案(如果有)?

非常感谢您抽出时间!

最佳答案

早在早期,当 RDBMS 的实现相当简单时,您实际上可以一直以这种方式手动优化事物。使用 IN( 的查询可能会表现更差。

现在,您可能仍然能够优化类似的事情,但仅限于极少数情况,因为 RDBMS 已经变得相当复杂,并且它们包含 Query Optimizers (wikipedia)它分析您的查询并以更优化的形式重述它,甚至考虑到您引用的各个表中的行数等因素。

因此,最好的选择是以最简单直接的形式陈述您的查询:

  SELECT job_number, customer_name, bill_customer 
      FROM job_log_test 
      INNER JOIN report_data 
      ON job_log_test.job_log_test_id = report_data.report_data_id
      WHERE bill_customer IS TRUE;

让查询优化器关心其余的事情。

此外,查询优化器的存在意味着您永远无法确定手动优化查询的尝试是否会产生更好或更差的结果。

当然,在某些情况下,您手动优化的查询可能比查询优化器可能提出的更好。在其他情况下,您的手动优化查询的表述方式可能会阻止查询优化器对其进行改进,因此您可能会获得比使用最简单形式更差的性能。最后,您手动优化的查询可能会让查询优化器更加困惑,从而产生更差的性能。

因此,如果您认为可以手动优化查询,请继续尝试一下,但始终将手动优化查询的性能与未优化查询的性能进行比较,您会在大多数情况下看到这一点(当然,并非所有)情况都是徒劳的。

关于mysql - MySQL 中的过滤行效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34213866/

相关文章:

mysql - 错误 1265 (01000) : Data truncated for column ' ' at row 1

mysql - PATH 变量中的多个应用程序

c# - 在开发计算机上运行 azure web 应用程序时出现数据库访问错误

sql - T-SQL解析XML赋予空白值

mysql - 有没有办法将这些查询合并为一个?

PHP - mySQL 数据库一直忽略我查询的第一部分

mysql - nodejs 和 mysql 连接失败?

sql - 查找表中连续的空闲号码

php - 如何使用单个查询从两个表中选择数据

连接表上大小写不工作的 MySQL 更新列