Dam*_*amo 8 mysql optimization sql-execution-plan
我有一个查询在两个数据集之间返回的时间差异很大.对于一组(数据库A),它会在几秒钟内返回,而另一组(数据库B)......我还没有等待足够长的时间,但是超过10分钟.我已将这两个数据库转储到本地计算机,我可以重现运行MySQL 5.1.37的问题.
奇怪的是,数据库B小于数据库A.
重现问题的查询的精简版本是:
SELECT * FROM po_shipment ps
JOIN po_shipment_item psi USING (ship_id)
JOIN po_alloc pa ON ps.ship_id = pa.ship_id AND pa.UID_items = psi.UID_items
JOIN po_header ph ON pa.hdr_id = ph.hdr_id
LEFT JOIN EVENT_TABLE ev0 ON ev0.TABLE_ID1 = ps.ship_id AND ev0.EVENT_TYPE = 'MAS0'
LEFT JOIN EVENT_TABLE ev1 ON ev1.TABLE_ID1 = ps.ship_id AND ev1.EVENT_TYPE = 'MAS1'
LEFT JOIN EVENT_TABLE ev2 ON ev2.TABLE_ID1 = ps.ship_id AND ev2.EVENT_TYPE = 'MAS2'
LEFT JOIN EVENT_TABLE ev3 ON ev3.TABLE_ID1 = ps.ship_id AND ev3.EVENT_TYPE = 'MAS3'
LEFT JOIN EVENT_TABLE ev4 ON ev4.TABLE_ID1 = ps.ship_id AND ev4.EVENT_TYPE = 'MAS4'
LEFT JOIN EVENT_TABLE ev5 ON ev5.TABLE_ID1 = ps.ship_id AND ev5.EVENT_TYPE = 'MAS5'
WHERE ps.eta >= '2010-03-22'
GROUP BY ps.ship_id
LIMIT 100;
Run Code Online (Sandbox Code Playgroud)
在~2秒内返回的第一个数据库(A)的EXPLAIN查询计划是:
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | ps | range | PRIMARY,IX_ETA_DATE | IX_ETA_DATE | 4 | NULL | 174 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev1 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev2 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev3 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev4 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev5 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | psi | ref | PRIMARY,IX_po_shipment_item_po_shipment1,FK_po_shipment_item_po_shipment1 | IX_po_shipment_item_po_shipment1 | 4 | UNIVIS_PROD.ps.ship_id | 1 | |
| 1 | SIMPLE | pa | ref | IX_po_alloc_po_shipment_item2,IX_po_alloc_po_details_old,FK_po_alloc_po_shipment1,FK_po_alloc_po_shipment_item1,FK_po_alloc_po_header1 | FK_po_alloc_po_shipment1 | 4 | UNIVIS_PROD.psi.ship_id | 5 | Using where |
| 1 | SIMPLE | ph | eq_ref | PRIMARY,IX_HDR_ID | PRIMARY | 4 | UNIVIS_PROD.pa.hdr_id | 1 | |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
在> 600秒内返回的第二个数据库(B)的EXPLAIN查询计划是:
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+--------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+--------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | ps | range | PRIMARY,IX_ETA_DATE | IX_ETA_DATE | 4 | NULL | 38 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | psi | ref | PRIMARY,IX_po_shipment_item_po_shipment1,FK_po_shipment_item_po_shipment1 | IX_po_shipment_item_po_shipment1 | 4 | UNIVIS_DEV01.ps.ship_id | 1 | |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.psi.ship_id,const | 1 | |
| 1 | SIMPLE | ev1 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.psi.ship_id,const | 1 | |
| 1 | SIMPLE | ev2 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev3 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.psi.ship_id,const | 1 | |
| 1 | SIMPLE | ev4 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.psi.ship_id,const | 1 | |
| 1 | SIMPLE | ev5 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | pa | ref | IX_po_alloc_po_shipment_item2,IX_po_alloc_po_details_old,FK_po_alloc_po_shipment1,FK_po_alloc_po_shipment_item1,FK_po_alloc_po_header1 | IX_po_alloc_po_shipment_item2 | 4 | UNIVIS_DEV01.ps.ship_id | 4 | Using where |
| 1 | SIMPLE | ph | eq_ref | PRIMARY,IX_HDR_ID | PRIMARY | 4 | UNIVIS_DEV01.pa.hdr_id | 1 | |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+--------------------------------+------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
当数据库B正在运行时,我可以查看MySQL管理员,状态将无限期地保留在"正在复制到tmp表".数据库A也有这种状态,但只有一秒左右.
这些数据库之间的表结构,索引,键等没有区别(我已经完成了show create tables和diff'd).
表的大小是:
database A:
po_shipment 1776
po_shipment_item 1945
po_alloc 36298
po_header 71642
EVENT_TABLE 1608
database B:
po_shipment 463
po_shipment_item 470
po_alloc 3291
po_header 56149
EVENT_TABLE 1089
Run Code Online (Sandbox Code Playgroud)
有些要点需要注意:
AJ回答后的更新: - 数据库B(最大值= 800002752)上ship_id的大小明显大于数据库A(最大值= 3489).鉴于这些是InnoDB表会更改任何缓冲区帮助处理这个大小的键?进一步更新:我减小了键的大小并重新分析,但性能仍然没有变化.
更新 EVENT_TABLE的desc:
请注意,它在两个数据库中都是相同的
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| EVENT_TABLE_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| EVENT_TYPE | varchar(10) | NO | | NULL | |
| TABLE_ID1 | int(11) | NO | MUL | NULL | |
| TABLE_ID2 | int(11) | YES | | NULL | |
| TABLE_ID3 | int(11) | YES | | NULL | |
| TABLE_ID4 | int(11) | YES | | NULL | |
| EVENT_CREATED_DATE | datetime | NO | | NULL | |
| MESSAGE_REF | varchar(100) | YES | | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
为了更好地衡量SHOW CREATE TABLE EVENT_TABLE:
数据库之间唯一不同的是自动增量值
| EVENT_TABLE | CREATE TABLE `EVENT_TABLE` (
`EVENT_TABLE_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`EVENT_TYPE` varchar(10) NOT NULL,
`TABLE_ID1` int(11) NOT NULL,
`TABLE_ID2` int(11) DEFAULT NULL,
`TABLE_ID3` int(11) DEFAULT NULL,
`TABLE_ID4` int(11) DEFAULT NULL,
`EVENT_CREATED_DATE` datetime NOT NULL,
`MESSAGE_REF` varchar(100) DEFAULT NULL,
PRIMARY KEY (`EVENT_TABLE_ID`),
KEY `IX_EVENT_ID_EVENT_TYPE` (`TABLE_ID1`,`EVENT_TYPE`)
) ENGINE=InnoDB AUTO_INCREMENT=1925 DEFAULT CHARSET=utf8 |
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议如何解决这个问题?我错过了什么?
Michael Holzmann提问之后的更新 以下是基于他更新的STRAIGHT_JOIN查询的新查询计划.请注意,数据库B具有"使用临时;使用filesort",而现在数据库A没有.这可能是由于长键或类似的东西?
数据库A.
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+-------------+
| 1 | SIMPLE | ps | index | PRIMARY,IX_ETA_DATE | PRIMARY | 4 | NULL | 168 | Using where |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev1 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev2 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev3 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev4 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev5 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | psi | ref | PRIMARY,IX_po_shipment_item_po_shipment1,FK_po_shipment_item_po_shipment1 | IX_po_shipment_item_po_shipment1 | 4 | UNIVIS_PROD.ps.ship_id | 1 | |
| 1 | SIMPLE | pa | ref | IX_po_alloc_po_shipment_item2,IX_po_alloc_po_details_old,FK_po_alloc_po_shipment1,FK_po_alloc_po_shipment_item1,FK_po_alloc_po_header1 | FK_po_alloc_po_shipment_item1 | 8 | UNIVIS_PROD.psi.UID_items | 6 | Using where |
| 1 | SIMPLE | ph | eq_ref | PRIMARY,IX_HDR_ID | PRIMARY | 4 | UNIVIS_PROD.pa.hdr_id | 1 | |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+------------------------------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
数据库B.
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | ps | range | PRIMARY,IX_ETA_DATE | IX_ETA_DATE | 4 | NULL | 38 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev1 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev2 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev3 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev4 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev5 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_DEV01.ps.ship_id,const | 1 | |
| 1 | SIMPLE | psi | ref | PRIMARY,IX_po_shipment_item_po_shipment1,FK_po_shipment_item_po_shipment1 | IX_po_shipment_item_po_shipment1 | 4 | UNIVIS_DEV01.ps.ship_id | 1 | |
| 1 | SIMPLE | pa | ref | IX_po_alloc_po_shipment_item2,IX_po_alloc_po_details_old,FK_po_alloc_po_shipment1,FK_po_alloc_po_shipment_item1,FK_po_alloc_po_header1 | IX_po_alloc_po_shipment_item2 | 4 | UNIVIS_DEV01.ps.ship_id | 3 | Using where |
| 1 | SIMPLE | ph | eq_ref | PRIMARY,IX_HDR_ID | PRIMARY | 4 | UNIVIS_DEV01.pa.hdr_id | 1 | |
+----+-------------+-------+--------+----------------------------------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------------+------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
更新它绝对是数据相关的.我从数据库A转储数据并使用以下方法将其加载到数据库B中:
SELECT * from <table> into outfile <file>
Run Code Online (Sandbox Code Playgroud)
和
LOAD DATA INFILE <file> into table <table>
Run Code Online (Sandbox Code Playgroud)
然后数据库B查询快速运行 - 即.和数据库A一样快.关于如何诊断数据可能出错的任何想法?
更新 @newtover:来自数据库A:
+-----------------+---------------------+
| eta_selectivity | ship_id_selectivity |
+-----------------+---------------------+
| 0.0693 | 1.0000 |
+-----------------+---------------------+
1 row in set (0.02 sec)
Run Code Online (Sandbox Code Playgroud)
来自数据库B(坏的)
+-----------------+---------------------+
| eta_selectivity | ship_id_selectivity |
+-----------------+---------------------+
| 0.1814 | 1.0000 |
+-----------------+---------------------+
1 row in set (0.02 sec)
Run Code Online (Sandbox Code Playgroud)
这个节目为po_shipment创造:
| po_shipment | CREATE TABLE `po_shipment` (
`ship_id` int(11) NOT NULL DEFAULT '0',
`ship_type` varchar(16) DEFAULT NULL,
`foreign_agent` varchar(16) DEFAULT NULL,
`agent_ref` varchar(16) DEFAULT NULL,
`exporter_code` varchar(30) DEFAULT NULL,
`importer_code` varchar(30) DEFAULT NULL,
`carrier_code` varchar(30) DEFAULT NULL,
`exporter_name` varchar(50) DEFAULT NULL,
`importer_name` varchar(50) DEFAULT NULL,
`carrier_name` varchar(50) DEFAULT NULL,
`receipt` varchar(30) DEFAULT NULL,
`pol_aol` varchar(50) DEFAULT NULL,
`pod_aod` varchar(30) DEFAULT NULL,
`final_dest` varchar(50) DEFAULT NULL,
`vessel_flno` varchar(30) DEFAULT NULL,
`ets` date DEFAULT NULL,
`eta` date DEFAULT NULL,
`pieces` int(11) DEFAULT '0',
`weight` decimal(17,2) DEFAULT '0.00',
`volume` decimal(17,2) DEFAULT '0.00',
`marks` varchar(500) DEFAULT NULL,
`goods_desc` varchar(500) DEFAULT NULL,
`ship_terms` varchar(16) DEFAULT NULL,
`ship_terms_desc` varchar(50) DEFAULT NULL,
`house_hawb` varchar(30) DEFAULT NULL,
`ocean_mawb` varchar(30) DEFAULT NULL,
`booking_date` date DEFAULT NULL,
`expected_cargo` date DEFAULT NULL,
`mfrt_jobdisp` varchar(30) DEFAULT NULL,
`ship_complete` date DEFAULT NULL,
`user_id` varchar(30) DEFAULT NULL,
`receipt_desc` varchar(60) DEFAULT NULL,
`fin_dest_desc` varchar(60) DEFAULT NULL,
`pol_aol_desc` varchar(60) DEFAULT NULL,
`pod_aod_desc` varchar(60) DEFAULT NULL,
`exporter_ref` varchar(26) DEFAULT NULL,
`carrier_ref` varchar(26) DEFAULT NULL,
`terms_conds` date DEFAULT NULL,
`last_amended` date DEFAULT NULL,
`user_amended` varchar(30) DEFAULT NULL,
`package_type` varchar(24) DEFAULT NULL,
`ext_cancelled` tinyint(1) NOT NULL DEFAULT '0',
`ext_goh` tinyint(1) NOT NULL DEFAULT '0',
`ext_arrival_date` date DEFAULT NULL,
`ext_booking_ref` varchar(255) DEFAULT NULL,
`ext_dc_booked_delivery_date` date DEFAULT NULL,
`ext_dc_booked_delivery_time` varchar(10) DEFAULT NULL,
`ext_comments` text,
`deleted` tinyint(1) NOT NULL DEFAULT '0',
`last_amended_time` int(10) DEFAULT NULL,
`last_amended_uni` varchar(30) DEFAULT NULL,
PRIMARY KEY (`ship_id`),
KEY `IX_ETA_DATE` (`eta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
Run Code Online (Sandbox Code Playgroud)
UPDATE @chris_I If I strip the query down by removing all other joins aside from EVENT_TABLE I get the same performance (ie. crappy)
SELECT * FROM po_shipment ps
LEFT JOIN EVENT_TABLE ev0 ON ev0.TABLE_ID1 = ps.ship_id AND ev0.EVENT_TYPE = 'MAS0'
LEFT JOIN EVENT_TABLE ev1 ON ev1.TABLE_ID1 = ps.ship_id AND ev1.EVENT_TYPE = 'MAS1'
LEFT JOIN EVENT_TABLE ev2 ON ev2.TABLE_ID1 = ps.ship_id AND ev2.EVENT_TYPE = 'MAS2'
LEFT JOIN EVENT_TABLE ev3 ON ev3.TABLE_ID1 = ps.ship_id AND ev3.EVENT_TYPE = 'MAS3'
LEFT JOIN EVENT_TABLE ev4 ON ev4.TABLE_ID1 = ps.ship_id AND ev4.EVENT_TYPE = 'MAS4'
LEFT JOIN EVENT_TABLE ev5 ON ev5.TABLE_ID1 = ps.ship_id AND ev5.EVENT_TYPE = 'MAS5'
WHERE ps.eta >= '2010-03-22'
GROUP BY ps.ship_id
LIMIT 100;
Run Code Online (Sandbox Code Playgroud)
UPDATE @Marcus Adams: Query for plans you have asked for with inner joins removed:
SELECT * FROM po_shipment ps
LEFT JOIN EVENT_TABLE ev0 ON ev0.TABLE_ID1 = ps.ship_id AND ev0.EVENT_TYPE = 'MAS0'
LEFT JOIN EVENT_TABLE ev1 ON ev1.TABLE_ID1 = ps.ship_id AND ev1.EVENT_TYPE = 'MAS1'
LEFT JOIN EVENT_TABLE ev2 ON ev2.TABLE_ID1 = ps.ship_id AND ev2.EVENT_TYPE = 'MAS2'
LEFT JOIN EVENT_TABLE ev3 ON ev3.TABLE_ID1 = ps.ship_id AND ev3.EVENT_TYPE = 'MAS3'
LEFT JOIN EVENT_TABLE ev4 ON ev4.TABLE_ID1 = ps.ship_id AND ev4.EVENT_TYPE = 'MAS4'
LEFT JOIN EVENT_TABLE ev5 ON ev5.TABLE_ID1 = ps.ship_id AND ev5.EVENT_TYPE = 'MAS5'
WHERE ps.eta >= '2010-03-22'
GROUP BY ps.ship_id
LIMIT 100;
Run Code Online (Sandbox Code Playgroud)
Query Plan from database A (responds in 0.35s)
+----+-------------+-------+-------+------------------------+------------------------+---------+------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------------------+------------------------+---------+------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | ps | range | IX_ETA_DATE | IX_ETA_DATE | 4 | NULL | 174 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev1 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev2 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev3 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev4 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
| 1 | SIMPLE | ev5 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36 | UNIVIS_PROD.ps.ship_id,const | 1 | |
+----+-------------+-------+-------+------------------------+------------------------+---------+------------------------------+------+----------------------------------------------
Run Code Online (Sandbox Code Playgroud)
Query Plan from database B (doesn't respond in time it takes to make a cup of tea)
+----+-------------+-------+-------+------------------------+------------------------+---------+-------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------------------+------------------------+---------+-------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | ps | range | IX_ETA_DATE | IX_ETA_DATE | 4 | NULL | 38 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | ev0 | ref | IX_EVENT_ID_EVENT_TYPE | IX_EVENT_ID_EVENT_TYPE | 36
Run Code Online (Sandbox Code Playgroud)
如果是数据问题,我无法告诉您确切的问题是什么,但这是我最喜欢的解决此类问题的策略:
尝试删除一半的连接。递归地重复,直到查询运行得很快。然后添加您在上一步中删除的连接的一半...(此策略比通过连接删除和添加连接所需的步骤要少得多。)
一旦发现“坏”连接,您可以尝试使用附加的“where”子句限制其值,直到查询再次快速运行......在每个步骤中,始终尝试将问题减少一半。
注意:很可能的情况是,即使数据库 B 中的数据总量较小,您也会获得更多连接中间结果的记录。