我有两个连接多个表的PostgreSQL查询:
第一的:
SELECT iradio.id, iradio.name, iradio.url, iradio.bandwidth, genre_trans.name FROM service_iradio_table AS iradio, genre_table AS genre, genre_name_table AS genre_name, genre_name_translation_table AS genre_trans, genre_mapping_table AS genre_mapping, language_code_table AS code WHERE iradio.id=genre_mapping.s_id AND genre_mapping.g_id=genre.id AND genre.id=genre_name.g_id AND genre_name.t_id=genre_trans.id AND genre_trans.code_id=code.id AND iradio.name='MyRadio' AND code.language_iso_code='ger'
第二:
SELECT iradio.id, iradio.name, iradio.url, iradio.bandwidth, genre_trans.name FROM service_iradio_table AS iradio INNER JOIN genre_mapping_table AS genre_mapping ON iradio.id=genre_mapping.s_id INNER JOIN genre_table AS genre ON genre_mapping.g_id=genre.id INNER JOIN genre_name_table AS genre_name ON genre.id=genre_name.g_id INNER JOIN genre_name_translation_table AS genre_trans ON genre_name.t_id=genre_trans.id INNER JOIN language_code_table AS code ON genre_trans.code_id=code.id WHERE iradio.name='MyRadio' AND code.language_iso_code='ger'
因此,来自MySQL我认为,由于交叉引用每个表,因此第一个查询的速度必须慢于第二个查询的速度。
似乎在postgreSQL中,这两个查询在内部是相同的。对于两个查询,使用关键字“ EXPLAIN”时,输出是相同的。
问题
这些查询是否真的是“相等的”?完全以这种方式联接表是goog设计吗?
最后,这种性能调整尝试也与“ EXPLAIN”运行到相同的输出中:
SELECT iradio.id, iradio.name, iradio.url, iradio.bandwidth, genre_trans.name FROM service_iradio_table AS iradio INNER JOIN genre_mapping_table AS genre_mapping ON iradio.id=genre_mapping.s_id AND iradio.name='MyRadio', genre_table AS genre, genre_name_table AS genre_name, genre_name_translation_table AS genre_trans, language_code_table AS code WHERE genre_mapping.g_id=genre.id AND genre.id=genre_name.g_id AND genre_name.t_id=genre_trans.id AND genre_trans.code_id=code.id AND code.language_iso_code='ger'
所有查询均在2ms内处理完毕。
当试图优化连接顺序时,查询计划者将(几乎)以相同的方式考虑所有WHERE和JOIN谓词。获得相同的性能也就不足为奇了。每个文档:
WHERE
JOIN
显式内部联接语法(INNER JOIN,CROSS JOIN或unadorned JOIN)在语义上与列出中的输入关系相同FROM,因此它不限制联接顺序。
INNER JOIN
CROSS JOIN
FROM
唯一的区别是:当表的总数大于的设置时,显式联接语法指示给定的联接顺序join_collapse_limit。
join_collapse_limit
显式JOINs绑定在FROM列表中的逗号之前,这与允许的语法有关。例子。
无论如何,FROM子句中 以 逗号分隔的表列表 绝不被弃用 。这是一种 很好的形式, 并且使用显式联接语法 更具可读性 。
还要注意,OUTER联接的行为有所不同,因为逻辑上的影响,查询计划人员无法随意重新排列联接。
OUTER