我注意到View与生成该视图的基础Select语句之间的性能差异。
创建View时,它会对所有基础表(大约700万行)执行表扫描,但Select语句不会执行此类扫描。
有人可以解释为什么会有区别吗?我如何使View像Select语句一样表现?
说明可以在Google表格中找到两个查询的计划:Link
选择声明: 更新:我已将问题缩小到以下Select语句。看起来像Group By或Group Concat可能会引起这个问题。
SELECT
-- IOHD_REQUEST fields
r.ID as requestIdMultiple
-- KEYVALUE and MULTIPLE fields
, CAST(GROUP_CONCAT(kv6.VALUE)AS CHAR(255)) AS CLIENT_ID
, CAST(GROUP_CONCAT(kv1.VALUE) AS CHAR(255)) AS IDENTIFIER_ID
, CAST(GROUP_CONCAT(ri.IDENTIFIER) AS CHAR(255)) AS IDENTIFIER
, CAST(GROUP_CONCAT(kv7.VALUE) AS CHAR(255)) AS PLATFORM_ID
, CAST(GROUP_CONCAT(kv8.VALUE) AS CHAR(255)) AS VENDOR_ID
FROM IOHD_REQUEST r
LEFT JOIN IOHD_REQUEST_HELPDESK rh ON r.ID = rh.REQUEST_ID
LEFT JOIN IOHD_REQUEST_CLIENT rc ON r.ID = rc.REQUEST_ID
LEFT JOIN IOHD_REQUEST_IDENTIFIER ri ON r.ID = ri.REQUEST_ID
LEFT JOIN IOHD_REQUEST_PLATFORM rp ON r.ID = rp.REQUEST_ID
LEFT JOIN IOHD_REQUEST_VENDOR rv ON r.ID = rv.REQUEST_ID
LEFT JOIN IOHD_REF_KEYVALUE kv1 ON (ri.IDENTIFIER_ID = kv1.KEY AND kv1.TYPE = 'IDENTIFIERTYPE')
LEFT JOIN IOHD_REF_KEYVALUE kv6 ON (rc.CLIENT_ID = kv6.KEY AND kv6.TYPE = 'CLIENT')
LEFT JOIN IOHD_REF_KEYVALUE kv7 ON (rp.PLATFORM_ID = kv7.KEY AND kv7.TYPE = 'PLATFORM')
LEFT JOIN IOHD_REF_KEYVALUE kv8 ON (rv.VENDOR_ID = kv8.KEY AND kv8.TYPE = 'VENDOR')
GROUP BY r.ID;
以下是在视图解释计划中抛弃我的界限。计划中的所有后续行在视图和select语句之间是相同的:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 7237546 100 NULL
指数
--
-- Indexes for table `IOHD_REF_KEYVALUE`
--
ALTER TABLE `IOHD_REF_KEYVALUE`
ADD PRIMARY KEY (`ID`),
ADD KEY `TYPE` (`TYPE`,`KEY`);
--
-- Indexes for table `IOHD_REQUEST`
--
ALTER TABLE `IOHD_REQUEST`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `IOHD_REQUEST_CLIENT`
--
ALTER TABLE `IOHD_REQUEST_CLIENT`
ADD PRIMARY KEY (`ID`),
ADD KEY `REQUEST_ID` (`REQUEST_ID`);
--
-- Indexes for table `IOHD_REQUEST_HELPDESK`
--
ALTER TABLE `IOHD_REQUEST_HELPDESK`
ADD PRIMARY KEY (`ID`),
ADD KEY `REQUEST_ID` (`REQUEST_ID`);
--
-- Indexes for table `IOHD_REQUEST_IDENTIFIER`
--
ALTER TABLE `IOHD_REQUEST_IDENTIFIER`
ADD PRIMARY KEY (`ID`),
ADD KEY `REQUEST_ID` (`REQUEST_ID`);
--
-- Indexes for table `IOHD_REQUEST_PLATFORM`
--
ALTER TABLE `IOHD_REQUEST_PLATFORM`
ADD PRIMARY KEY (`ID`),
ADD KEY `REQUEST_ID` (`REQUEST_ID`);
--
-- Indexes for table `IOHD_REQUEST_VENDOR`
--
ALTER TABLE `IOHD_REQUEST_VENDOR`
ADD PRIMARY KEY (`ID`),
ADD KEY `REQUEST_ID` (`REQUEST_ID`);
答案 0 :(得分:0)
哦,键值模式的问题。除了放弃设计模式之外,让我们看一下改进索引。
IOHD_REF_KEYVALUE
迫切需要帮助。
PRIMARY KEY(TYPE, KEY)
- (相反的顺序没问题)id
。正在发生“爆炸性内爆”。那是JOIN
导致更多行; GROUP BY
将其恢复原状。同时建造了一个巨大的tmp桌子。部分治愈是取代
CAST(GROUP_CONCAT(kv6.VALUE)AS CHAR(255)) AS CLIENT_ID
and
LEFT JOIN IOHD_REF_KEYVALUE kv6 ON (rc.CLIENT_ID = kv6.KEY AND kv6.TYPE = 'CLIENT')
与
( SELECT GROUP_CONCAT(VALUE)
FROM IOHD_REF_KEYVALUE
WHERE KEY = rc.CLIENT_ID
AND TYPE = 'CLIENT'
) AS CLIENT_ID
(类似案例也是如此。)
在您修复了所需内容之后,请回来寻求更多帮助,但一定要带上SHOW CREATE TABLE
和EXPLAIN SELECT ...