[英]Optimization of a MySQL query in php
如何優化以下查詢
CREATE TABLE $fullTableName AS (
SELECT COUNT(*) AS `impCnt`,
IF(COUNT(*)>7,7,COUNT(*)) AS `impGroup`,
MIN(ad.`created`) AS `dateFirstImp`,
ad.sid,
IF(cl.`clicks` IS NULL, 0, cl.`clicks`) AS `clickCnt`,
st.`panelistID` AS panelistID,
SUBSTRING_INDEX(GROUP_CONCAT(NULLIF(lbs.`site`, '') ORDER BY lbs.`table-order`,lbs.`value-order` ASC SEPARATOR '~'),'~',1) as 'site',
SUBSTRING_INDEX(GROUP_CONCAT(NULLIF(lbs.`dimension`, '') ORDER BY lbs.`table-order`,lbs.`value-order` ASC SEPARATOR '~'),'~',1) as 'dimension'
FROM table1 ad
LEFT JOIN (
SELECT t.`parameter` as 'parameter', v.`value` as 'value',
IF(FIND_IN_SET('site',t.attributes),v.`site`,null) as 'site',
IF(FIND_IN_SET('placement',t.attributes),v.`placement`,null) as 'placement',
IF(FIND_IN_SET('format',t.attributes),v.`format`,null) as 'format',
IF(FIND_IN_SET('creative',t.attributes),v.`creative`,null) as 'creative',
IF(FIND_IN_SET('mediaOwner',t.attributes),v.`mediaOwner`,null) as 'mediaOwner',
IF(FIND_IN_SET('targeting',t.attributes),v.`targeting`,null) as 'targeting',
IF(FIND_IN_SET('dimension',t.attributes),v.`dimension`,null) as 'dimension',
t.`order` as 'table-order', v.`order` as 'value-order' FROM table2 t
JOIN table3 v ON (t.tableID=v.tableID) WHERE t.campaignID = 1856
AND t.`active`=1 AND t.`ignore`=0 ORDER BY t.`order`,v.`order`
) lbs ON ($string)
LEFT JOIN (
SELECT cl2.`memberid` as memberid,
cl2.`panelid` as panelid,COUNT(*) as clicks
FROM table4 cl2 WHERE 1 AND (1) GROUP BY cl2.`memberid`,cl2.`panelid`
) cl
ON (ad.`memberid`=cl.`memberid` AND ad.`panelid`=cl.`panelid`)
LEFT JOIN table5 st
ON (ad.`memberid`=st.`panelistID` AND ad.`panelid`=st.`panelID`)
JOIN table6 ef
ON (ef.`panelID`=st.`panelID` AND ef.`panelistID`=st.`panelistID`)
WHERE 1 AND (1) GROUP BY ad.`memberid`, ad.`panelid` ORDER BY ad.`memberid` ASC, ad.`panelid` ASC)
想到了各種各樣的問題......首先,出於可讀性目的對查詢進行一些清理......
SELECT
COUNT(*) AS impCnt,
IF( COUNT(*) > 7, 7 , COUNT(*) ) AS impGroup,
MIN(ad.created) AS dateFirstImp,
ad.sid,
IF(cl.clicks IS NULL, 0, cl.clicks ) AS clickCnt,
st.panelistID,
SUBSTRING_INDEX(GROUP_CONCAT(NULLIF(lbs.site, '') ORDER BY lbs.`table-order`, lbs.`value-order` ASC SEPARATOR '~'),'~',1) as 'site',
SUBSTRING_INDEX(GROUP_CONCAT(NULLIF(lbs.dimension, '') ORDER BY lbs.`table-order`,lbs.`value-order` ASC SEPARATOR '~'),'~',1) as 'dimension'
FROM
table1 ad
LEFT JOIN ( SELECT
t.`parameter` as 'parameter',
v.`value` as 'value',
IF(FIND_IN_SET('site',t.attributes),v.site,null) as 'site',
IF(FIND_IN_SET('placement',t.attributes),v.placement,null) as 'placement',
IF(FIND_IN_SET('format',t.attributes),v.format,null) as 'format',
IF(FIND_IN_SET('creative',t.attributes),v.creative,null) as 'creative',
IF(FIND_IN_SET('mediaOwner',t.attributes),v.mediaOwner,null) as 'mediaOwner',
IF(FIND_IN_SET('targeting',t.attributes),v.targeting,null) as 'targeting',
IF(FIND_IN_SET('dimension',t.attributes),v.dimension,null) as 'dimension',
t.`order` as 'table-order',
v.`order` as 'value-order'
FROM
table2 t
JOIN table3 v
ON t.tableID = v.tableID
WHERE
t.campaignID = 1856
AND t.active = 1
AND t.ignore = 0
ORDER BY
t.`order`,
v.`order` ) lbs
ON ($string)
LEFT JOIN ( SELECT
cl2.memberid as memberid,
cl2.panelid as panelid,
COUNT(*) as clicks
FROM
table4 cl2
WHERE
1 AND (1)
GROUP BY
cl2.memberid,
cl2.panelid ) cl
ON ad.memberid = cl.memberid
AND ad.panelid = cl.panelid
LEFT JOIN table5 st
ON ad.memberid = st.panelistID
AND ad.panelid = st.panelID
JOIN table6 ef
ON ef.panelID = st.panelID
AND ef.panelistID = st.panelistID
WHERE
1 AND (1)
GROUP BY
ad.memberid,
ad.panelid
ORDER BY
ad.memberid ASC,
ad.panelid ASC
您顯然試圖通過您的表名進行泛型化,但使用別名可以很好地顯示關系。
您加入基於 ($string) 的子查詢別名“lbs”,但沒有提供任何可能是什么的上下文/樣本——過濾和/或實際加入標准?
作為“lbs”別名基礎的內部選擇僅在最終外部查詢中使用“站點”和“維度”列......為什么對所有其他列執行 FIND_IN_SET 。
基於“lbs”查詢,您的 table2(t 別名)應該在(campaignID, active, ignore, order )上有一個復合索引,以幫助優化查詢的那部分和 order by 子句。
針對您的(廣告別名)表的最終 group by / order by 應至少在 ( memberid, panelid ) 上有一個復合索引,並根據您從“廣告”中尋找的“標准”在這些列的前面添加額外的列桌子。
根據您的“WHERE 1 AND (1)”標准,您的(cl2 別名)應該在( memberid, panelid )加上附加列上有一個復合索引,這些列是不明確的,只是實際過濾標准的占位符。 如果沒有示例真實上下文,我們就無法為您提供更好的索引列優化。
“1 AND (1)”的最后一個 WHERE 子句......與#5 相同的歧義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.