需要帮助优化 MySQL 具有少量连接的查询
Need Help for Optimizing MySQL query with few joins
你好,我有以下 sql 查询,它有效,但有点慢
SELECT
ep . *,
t_u.sUsername AS sLockedBy,
epi.sName,
em.sName AS sManufacturerName,
SUM(IF(eop.dInProduction IS NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductOrdered,
SUM(IF(eop.dInProduction IS NOT NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductInProduction,
SUM(IF(eop.dInProduction IS NOT NULL
AND eop.dFromProduction IS NOT NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductFromProduction,
SUM(IF(eop.dInProduction IS NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) + ep.nInStock AS nStockCheck
FROM
eshop3_products AS ep
LEFT JOIN
users AS t_u ON ep.nUserLockID = t_u.nUID
AND t_u.nDeleted = 0
INNER JOIN
eshop3_products_i18n AS epi ON ep.nUID = epi.nProductID
AND epi.nLangID = 1
AND epi.nDeleted = 0
LEFT JOIN
eshop3_manufacturers AS em ON ep.nManufacturerID = em.nUID
AND em.nDeleted = 0
LEFT JOIN
eshop3_order_products AS eop ON ep.nUID = eop.nProductID
LEFT JOIN
eshop3_orders AS eo ON eop.nOrderID = eo.nUID
LEFT JOIN
eshop3_order_statuses AS eos ON eo.nUID = eos.nOrderID
AND eos.nUID = (SELECT
nUID
FROM
eshop3_order_statuses as eos
WHERE
eo.nUID = eos.nOrderID
ORDER BY eos.nUID DESC
LIMIT 1)
WHERE
(ep.nDeleted = 0)
GROUP BY ep.nUID
ORDER BY ep.sStoreCode ASC
产品 Table 共有 462 行,
订单状态 Tables 共有 17 154 行
查询的执行时间是 1.5 秒,我认为它很慢。
我在ON子句中使用INNER SELECT来获取给定订单的最后状态,这里我认为有问题。
当我从整个查询中删除订单状态 table 时,执行时间快了几倍 0.152 秒
你能给我一些建议吗我怎样才能优化我的查询
给你sql解释
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY epi ALL nProductID 408 Using where; Using temporary; Using filesort
1 PRIMARY ep eq_ref PRIMARY,nUID PRIMARY 4 dragoni_zfms.epi.nProductID 1 Using where
1 PRIMARY em eq_ref PRIMARY PRIMARY 4 dragoni_zfms.ep.nManufacturerID 1
1 PRIMARY t_u eq_ref PRIMARY PRIMARY 4 dragoni_zfms.ep.nUserLockID 1
1 PRIMARY eop ref id_productid id_productid 5 dragoni_zfms.ep.nUID 13
1 PRIMARY eo eq_ref PRIMARY PRIMARY 4 dragoni_zfms.eop.nOrderID 1 Using index
1 PRIMARY eos eq_ref PRIMARY,nOrderID PRIMARY 4 func 1
2 DEPENDENT SUBQUERY eos ref nOrderID nOrderID 4 dragoni_zfms.eo.nUID 1 Using where; Using index; Using filesort
在您的情况下,不使用 mysql 而使用 php 执行某些操作会更容易。
当你赢得时间时,我在我的实践案例中看到过。请尝试将一个复杂的查询分成几个简单的查询。然后使用 php 脚本执行必要的过滤。
希望能帮助到你。
谢谢!
你好,我有以下 sql 查询,它有效,但有点慢
SELECT
ep . *,
t_u.sUsername AS sLockedBy,
epi.sName,
em.sName AS sManufacturerName,
SUM(IF(eop.dInProduction IS NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductOrdered,
SUM(IF(eop.dInProduction IS NOT NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductInProduction,
SUM(IF(eop.dInProduction IS NOT NULL
AND eop.dFromProduction IS NOT NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) AS nProductFromProduction,
SUM(IF(eop.dInProduction IS NULL
AND eop.dFromProduction IS NULL
AND eop.dShipped IS NULL
AND eop.nIsCancelled = 0
AND eos.sStatusCode NOT IN ('Canceled' , 'Finished', 'Complete'),
1,
0)) + ep.nInStock AS nStockCheck
FROM
eshop3_products AS ep
LEFT JOIN
users AS t_u ON ep.nUserLockID = t_u.nUID
AND t_u.nDeleted = 0
INNER JOIN
eshop3_products_i18n AS epi ON ep.nUID = epi.nProductID
AND epi.nLangID = 1
AND epi.nDeleted = 0
LEFT JOIN
eshop3_manufacturers AS em ON ep.nManufacturerID = em.nUID
AND em.nDeleted = 0
LEFT JOIN
eshop3_order_products AS eop ON ep.nUID = eop.nProductID
LEFT JOIN
eshop3_orders AS eo ON eop.nOrderID = eo.nUID
LEFT JOIN
eshop3_order_statuses AS eos ON eo.nUID = eos.nOrderID
AND eos.nUID = (SELECT
nUID
FROM
eshop3_order_statuses as eos
WHERE
eo.nUID = eos.nOrderID
ORDER BY eos.nUID DESC
LIMIT 1)
WHERE
(ep.nDeleted = 0)
GROUP BY ep.nUID
ORDER BY ep.sStoreCode ASC
产品 Table 共有 462 行,
订单状态 Tables 共有 17 154 行
查询的执行时间是 1.5 秒,我认为它很慢。
我在ON子句中使用INNER SELECT来获取给定订单的最后状态,这里我认为有问题。
当我从整个查询中删除订单状态 table 时,执行时间快了几倍 0.152 秒
你能给我一些建议吗我怎样才能优化我的查询
给你sql解释
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY epi ALL nProductID 408 Using where; Using temporary; Using filesort
1 PRIMARY ep eq_ref PRIMARY,nUID PRIMARY 4 dragoni_zfms.epi.nProductID 1 Using where
1 PRIMARY em eq_ref PRIMARY PRIMARY 4 dragoni_zfms.ep.nManufacturerID 1
1 PRIMARY t_u eq_ref PRIMARY PRIMARY 4 dragoni_zfms.ep.nUserLockID 1
1 PRIMARY eop ref id_productid id_productid 5 dragoni_zfms.ep.nUID 13
1 PRIMARY eo eq_ref PRIMARY PRIMARY 4 dragoni_zfms.eop.nOrderID 1 Using index
1 PRIMARY eos eq_ref PRIMARY,nOrderID PRIMARY 4 func 1
2 DEPENDENT SUBQUERY eos ref nOrderID nOrderID 4 dragoni_zfms.eo.nUID 1 Using where; Using index; Using filesort
在您的情况下,不使用 mysql 而使用 php 执行某些操作会更容易。 当你赢得时间时,我在我的实践案例中看到过。请尝试将一个复杂的查询分成几个简单的查询。然后使用 php 脚本执行必要的过滤。 希望能帮助到你。 谢谢!