如何提高这个 View/Query 的性能?
How to increase the porformance of this View/Query?
我有 Mysql 查看它 运行 大约 9 秒。我真的需要提高这个视图的性能。这是我的代码:
SELECT
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID` AS `TRIP_ASSIGNMENT_DETAILS_ID`,
`lvdu`.`USERNAME` AS `USERNAME`,
`cdm`.`DOMICILE_LOOK_UP_ID` AS `DOMICILE_LOOK_UP_ID`,
CAST(
GROUP_CONCAT(
DISTINCT `ptlm`.`LOAD_ID` SEPARATOR ','
) AS CHAR(255) CHARSET utf8mb4
) AS `LOAD_RELATED`,
MIN(`ptlm`.`PLANNED_START_DATETIME`) AS `PLANNED_START_DATETIME`
FROM
`Appian`.`LDA_TRIP_ASSIGNMENT_DETAILS` `tad`
LEFT JOIN `Appian`.`LDA_VIEW_DRIVER_AND_USER_DETAILS` `lvdu`
ON
(
`tad`.`DRIVER_DETAILS_ID` = `lvdu`.`DRIVER_DETAILS_ID`
)
LEFT JOIN `Appian`.`LDA_VIEW_CARRIER_DOMICILE_MAPPING` `cdm`
ON
(
`lvdu`.`CARRIER_LOOK_UP_ID` = `cdm`.`CARRIER_LOOK_UP_ID`
)
LEFT JOIN `Appian`.`LDA_POD_TRIP_LOAD_MAPPING` `ptlm`
ON
(
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID` = `ptlm`.`TRIP_ASSIGNMENT_ID`
)
WHERE
`tad`.`TRIP_STATUS` IN('Force De-Assigned', 'Completed') AND `tad`.`TRIP_ASSIGNED_TIME` > CURRENT_TIMESTAMP() - INTERVAL 10 DAY
GROUP BY
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID`
ORDER BY
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID`
DESC
查看LDA_VIEW_DRIVER_AND_USER_DETAILS(1329行)和LDA_VIEW_CARRIER_DOMICILE_MAPPING(216行)具有相当不错的性能和只需要0.01秒。但是一旦我 运行 这个查询大约需要 9 秒。
LDA_TRIP_ASSIGNMENT_DETAILS: 只有 19401 行
LDA_POD_TRIP_LOAD_MAPPING: 只有 11056 行
TRIP_ASSIGNMENT_DETAILS_ID是LDA_TRIP_ASSIGNMENT_DETAILS
的主键
LDA_POD_TRIP_LOAD_MAPPINGtable没有索引。
请给我一些解决这个问题的提示,
我将不胜感激!!!
需要猜测才能提供有关优化此查询的明确建议。为什么?
您还没有向我们展示 table 定义。
您没有向我们展示视图定义,或底层 table 的定义。
MySQL 查询规划器将视图定义编译到每个查询中,然后找出满足它的最佳方式。 Please read this for more information about how to put together a good query-optimizattion 问题。
话虽这么说, 你查询的这些部分突然出现在我面前。
SELECT tad.TRIP_ASSIGNMENT_DETAILS_ID AS TRIP_ASSIGNMENT_DETAILS_ID,
....
ON tad.DRIVER_DETAILS_ID = lvdu.DRIVER_DETAILS_ID
...
WHERE tad.TRIP_STATUS IN('Force De-Assigned', 'Completed')
AND tad.TRIP_ASSIGNED_TIME > CURRENT_TIMESTAMP() - INTERVAL 10 DAY
...
ORDER BY tad.TRIP_ASSIGNMENT_DETAILS_ID DESC
如果您创建覆盖索引,它可以优化您的 WHERE 子句并为您的 SELECT 和 ON 子句提供列数据。这可能有助于您的查询 运行 快速。
这是我建议的索引
CREATE INDEX TAD_LOOKUP
ON Appian.LDA_TRIP_ASSIGNMENT_DETAILS
(TRIP_STATUS,
TRIP_ASSIGNED_TIME,
TRIP_ASSIGNMENT_DETAILS_ID DESC,
DRIVER_DETAILS_ID);
这是 called a covering index,因为它包含满足您的查询所需的所有列。 TRIP_STATUS
是第一个,因为它在您的 WHERE 子句中显示为相等文件管理器。 TRIP_ASSIGNED_TIME
是第二个,因为它显示为范围匹配。这意味着 MySQL 可以随机访问索引到第一个相关行,然后按顺序扫描索引以获取所需的数据。
其他两列在索引中只是因为您的查询需要它们的值,而不是因为它们是搜索的一部分。
出于类似的原因,另一个索引可能也会有所帮助。
CREATE INDEX PTLM_LOOKUP
ON Appian.LDA_POD_TRIP_LOAD_MAPPING
(PTLM_TRIP_ASSIGNMENT_ID, LOAD_ID);
专业提示:您和下一个处理您代码的人能够对您的查询进行推理,这一点至关重要。这意味着将它们格式化为可读是值得你花在这上面的每一秒。看看上面我是如何格式化你的 WHERE 子句的,所以所有的过滤谓词都出现在左边距附近。 (我还省略了名字周围的反引号,因为它们激怒了我。但那只是我。)
我有 Mysql 查看它 运行 大约 9 秒。我真的需要提高这个视图的性能。这是我的代码:
SELECT
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID` AS `TRIP_ASSIGNMENT_DETAILS_ID`,
`lvdu`.`USERNAME` AS `USERNAME`,
`cdm`.`DOMICILE_LOOK_UP_ID` AS `DOMICILE_LOOK_UP_ID`,
CAST(
GROUP_CONCAT(
DISTINCT `ptlm`.`LOAD_ID` SEPARATOR ','
) AS CHAR(255) CHARSET utf8mb4
) AS `LOAD_RELATED`,
MIN(`ptlm`.`PLANNED_START_DATETIME`) AS `PLANNED_START_DATETIME`
FROM
`Appian`.`LDA_TRIP_ASSIGNMENT_DETAILS` `tad`
LEFT JOIN `Appian`.`LDA_VIEW_DRIVER_AND_USER_DETAILS` `lvdu`
ON
(
`tad`.`DRIVER_DETAILS_ID` = `lvdu`.`DRIVER_DETAILS_ID`
)
LEFT JOIN `Appian`.`LDA_VIEW_CARRIER_DOMICILE_MAPPING` `cdm`
ON
(
`lvdu`.`CARRIER_LOOK_UP_ID` = `cdm`.`CARRIER_LOOK_UP_ID`
)
LEFT JOIN `Appian`.`LDA_POD_TRIP_LOAD_MAPPING` `ptlm`
ON
(
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID` = `ptlm`.`TRIP_ASSIGNMENT_ID`
)
WHERE
`tad`.`TRIP_STATUS` IN('Force De-Assigned', 'Completed') AND `tad`.`TRIP_ASSIGNED_TIME` > CURRENT_TIMESTAMP() - INTERVAL 10 DAY
GROUP BY
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID`
ORDER BY
`tad`.`TRIP_ASSIGNMENT_DETAILS_ID`
DESC
查看LDA_VIEW_DRIVER_AND_USER_DETAILS(1329行)和LDA_VIEW_CARRIER_DOMICILE_MAPPING(216行)具有相当不错的性能和只需要0.01秒。但是一旦我 运行 这个查询大约需要 9 秒。
LDA_TRIP_ASSIGNMENT_DETAILS: 只有 19401 行
LDA_POD_TRIP_LOAD_MAPPING: 只有 11056 行
TRIP_ASSIGNMENT_DETAILS_ID是LDA_TRIP_ASSIGNMENT_DETAILS
的主键LDA_POD_TRIP_LOAD_MAPPINGtable没有索引。
请给我一些解决这个问题的提示,
我将不胜感激!!!
需要猜测才能提供有关优化此查询的明确建议。为什么?
您还没有向我们展示 table 定义。
您没有向我们展示视图定义,或底层 table 的定义。
MySQL 查询规划器将视图定义编译到每个查询中,然后找出满足它的最佳方式。 Please read this for more information about how to put together a good query-optimizattion 问题。
话虽这么说, 你查询的这些部分突然出现在我面前。
SELECT tad.TRIP_ASSIGNMENT_DETAILS_ID AS TRIP_ASSIGNMENT_DETAILS_ID,
....
ON tad.DRIVER_DETAILS_ID = lvdu.DRIVER_DETAILS_ID
...
WHERE tad.TRIP_STATUS IN('Force De-Assigned', 'Completed')
AND tad.TRIP_ASSIGNED_TIME > CURRENT_TIMESTAMP() - INTERVAL 10 DAY
...
ORDER BY tad.TRIP_ASSIGNMENT_DETAILS_ID DESC
如果您创建覆盖索引,它可以优化您的 WHERE 子句并为您的 SELECT 和 ON 子句提供列数据。这可能有助于您的查询 运行 快速。
这是我建议的索引
CREATE INDEX TAD_LOOKUP
ON Appian.LDA_TRIP_ASSIGNMENT_DETAILS
(TRIP_STATUS,
TRIP_ASSIGNED_TIME,
TRIP_ASSIGNMENT_DETAILS_ID DESC,
DRIVER_DETAILS_ID);
这是 called a covering index,因为它包含满足您的查询所需的所有列。 TRIP_STATUS
是第一个,因为它在您的 WHERE 子句中显示为相等文件管理器。 TRIP_ASSIGNED_TIME
是第二个,因为它显示为范围匹配。这意味着 MySQL 可以随机访问索引到第一个相关行,然后按顺序扫描索引以获取所需的数据。
其他两列在索引中只是因为您的查询需要它们的值,而不是因为它们是搜索的一部分。
出于类似的原因,另一个索引可能也会有所帮助。
CREATE INDEX PTLM_LOOKUP
ON Appian.LDA_POD_TRIP_LOAD_MAPPING
(PTLM_TRIP_ASSIGNMENT_ID, LOAD_ID);
专业提示:您和下一个处理您代码的人能够对您的查询进行推理,这一点至关重要。这意味着将它们格式化为可读是值得你花在这上面的每一秒。看看上面我是如何格式化你的 WHERE 子句的,所以所有的过滤谓词都出现在左边距附近。 (我还省略了名字周围的反引号,因为它们激怒了我。但那只是我。)