我有兩張桌子。 order_details
是100,000行,而outbound
是10,000行。爲什麼使用子查詢顯着加快此簡單聯接查詢?
我需要將它們加入名爲order_number
的列,這兩列上都是VARCHAR(50)。 order_number在出站表中不唯一。
CREATE TABLE `outbound` (
`outbound_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `order_details` (
`order_details_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這是我的初步查詢,它需要超過60秒運行:
SELECT o.order_number
FROM outbound o
INNER JOIN order_details od
ON o.order_number = od.order_number
該查詢得到同樣的結果和需要不到一秒鐘來運行:
SELECT o.order_number
FROM outbound o
INNER JOIN
(
SELECT order_number
FROM order_details
) od
ON (o.order_number = od.order_number)
這對我來說令人感到意外,因爲通常子查詢顯着較慢。
正在運行EXPLAIN
(我仍在學習如何理解)顯示子查詢版本使用derived2
表,它使用的是索引,該索引是auto_key0
。我不夠明白如何解釋這一點,以理解爲什麼這會產生重大影響。
我正在命令行上運行這些查詢。
我正在運行MySQL Ver 14.14 Distrib 5.6.35,用於Linux(x86_64)CentOS。
總結:
爲什麼這個簡單的用一個子查詢顯著更快的連接查詢?
MySQL的糟糕的優化器?你是否與「EXISTS」或「IN」進行比較? 'SELECT o.order_number FROM出站ö WHERE EXISTS(SELECT ORDER_NUMBER FROM ORDER_DETAILS AS OD WHERE o.order_number = od.order_number)'或'SELECT o.order_number FROM出站ö WHERE ORDER_NUMBER IN ( SELECT order_number FROM order_details )' – dnoeth
@dnoeth第一個查詢佔用了一分鐘,第二個查詢是即時的。 – Goose
正如我所說的,一個體面的優化器應該對待所有四個類似的(實際上,當order_details.orde_number不唯一時,連接可能會得到不同的結果)。 – dnoeth