我正在学习 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/