[英]SQL/PHP query optimization
我正在寻找有关优化查询的帮助,并希望以后自己了解如何做。
我已经导出了数据库以方便使用-https://www.dropbox.com/s/jwocqwuxl1bv3rt/DB_BF.zip?dl=0
在这些页面上可以看到查询的加载时间-
http://89.163.173.82/DCS/blueflag/Pilots.php
http://89.163.173.82/DCS/blueflag/Events.php
http://89.163.173.82/DCS/blueflag/Player.php?term=Reaper6
到目前为止,我尝试通过添加索引和减少选定的列来进行一些优化,但是效果不大。 我不确定如何更改这些大查询以执行相同的步骤,但已对其进行了优化。
第一次查询
SELECT DeadTbl.TIME AS 'Time',DeadTbl.Event AS 'Event',DeadTbl.InitiatorCoa AS 'Target Coalition',DeadTbl.InitiatorPlayer AS 'Target Player',DeadTbl.InitiatorType AS 'Target Type',DeadTbl.InitiatorGroupCat
,HitTbl.InitiatorCoa AS 'Coalition',HitTbl.InitiatorPlayer AS 'Player',HitTbl.InitiatorType AS 'Type',HitTbl.WeaponCat AS 'Weapon Category',HitTbl.WeaponName AS 'Weapon Name'
FROM (
SELECT TIME,InitiatorID,EVENT,InitiatorCoa,InitiatorType,InitiatorPlayer,InitiatorGroupCat
FROM BlueFlagR2
WHERE (EVENT = 'S_EVENT_DEAD'OR EVENT = 'S_EVENT_CRASH'OR EVENT = 'S_EVENT_PLAYER_LEAVE_UNIT')
AND InitiatorGroupCat != ''
) AS DeadTbl
JOIN (
SELECT MAX(`Time`) AS `Time`
,InitiatorID,InitiatorCoa,InitiatorPlayer,InitiatorType
,WeaponCat,WeaponName
,TargetID,TargetCoa,TargetType,TargetPlayer
FROM BlueFlagR2
WHERE EVENT = 'S_EVENT_HIT'
AND InitiatorID != 0
AND InitiatorPlayer != 'No Initiator'
GROUP BY InitiatorID,InitiatorPlayer,TargetID,TargetType
) AS HitTbl ON DeadTbl.InitiatorID = HitTbl.TargetID
AND DeadTbl.InitiatorCoa = HitTbl.TargetCoa
AND DeadTbl.InitiatorPlayer = HitTbl.TargetPlayer
AND DeadTbl.InitiatorType = HitTbl.TargetType
AND HitTbl.TIME <= DeadTbl.TIME
GROUP BY DeadTbl.InitiatorID,DeadTbl.TIME,HitTbl.InitiatorID
ORDER BY DeadTbl.TIME ASC
第二个查询:
SELECT K.Player AS Player, K.Ground AS Ground, K.Airplane AS Airplane, K.Helicopter AS Helicopter, K.Ship AS Ship, K.Total AS Total, IFNULL(D.Total,0) AS Deaths, (CASE WHEN D.Total IS NULL THEN K.Total ELSE K.Total/D.Total END) AS KD_Ratio
FROM
(
SELECT PlayerTable.Player AS 'Player', SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'GROUND_UNIT' THEN 1 ELSE 0 END) AS Ground, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'AIRPLANE' THEN 1 ELSE 0 END) AS Airplane, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'HELICOPTER' THEN 1 ELSE 0 END) AS Helicopter, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'SHIP' THEN 1 ELSE 0 END) AS Ship, COUNT(PlayerTable.`Target Player`) AS Total
FROM
(
SELECT DeadTbl.Time AS 'Time', HitTbl.InitiatorCoa AS 'Coalition', HitTbl.InitiatorPlayer AS 'Player', HitTbl.InitiatorType AS 'Type',HitTbl.WeaponCat AS 'Weapon Category',HitTbl.WeaponName AS 'Weapon Name', DeadTbl.Event AS 'Event', DeadTbl.InitiatorCoa AS 'Target Coalition', DeadTbl.InitiatorPlayer AS 'Target Player', DeadTbl.InitiatorType AS 'Target Type', DeadTbl.InitiatorGroupCat
FROM
(
SELECT TIME,InitiatorID,EVENT,InitiatorCoa,InitiatorType,InitiatorPlayer,InitiatorGroupCat
FROM BlueFlagR2
WHERE (EVENT = 'S_EVENT_DEAD' OR EVENT = 'S_EVENT_CRASH' OR EVENT='S_EVENT_PLAYER_LEAVE_UNIT')
AND InitiatorGroupCat != ''
) AS DeadTbl
JOIN
(
SELECT MAX(`Time`) AS `Time`,InitiatorID,InitiatorCoa,InitiatorPlayer,InitiatorType,WeaponCat,WeaponName,TargetID,TargetCoa,TargetType,TargetPlayer
FROM BlueFlagR2
WHERE EVENT = 'S_EVENT_HIT' AND InitiatorID!=0 AND InitiatorPlayer!='No Initiator'
GROUP BY InitiatorID,InitiatorPlayer,TargetID,TargetType
) AS HitTbl
ON DeadTbl.InitiatorID = HitTbl.TargetID AND DeadTbl.InitiatorCoa = HitTbl.TargetCoa AND DeadTbl.InitiatorPlayer = HitTbl.TargetPlayer AND DeadTbl.InitiatorType = HitTbl.TargetType AND HitTbl.Time <= DeadTbl.Time
GROUP BY DeadTbl.InitiatorID,DeadTbl.Time,HitTbl.InitiatorID
) AS PlayerTable
GROUP BY PlayerTable.Player
) AS K
LEFT JOIN
(
SELECT InitiatorPlayer, COUNT(*) AS Total
FROM BlueFlagR2
WHERE (EVENT = 'S_EVENT_DEAD' OR EVENT = 'S_EVENT_CRASH')
AND (InitiatorGroupCat = 'AIRPLANE' OR InitiatorGroupCat = 'HELICOPTER')
AND InitiatorPlayer != 'AI'
GROUP BY InitiatorPlayer
) AS D
ON K.Player = D.InitiatorPlayer
WHERE Player != 'AI' AND Player != '' AND Player != 'No Initiator'
ORDER BY CASE WHEN KD_Ratio = 'Infinite' THEN K.Total
ELSE KD_Ratio END DESC
它们基本上是相似的,因为其核心是相同的。
感谢任何帮助!
您还在使用或可以在其中使用的位置
(“ S_EVENT_DEAD”,“ S_EVENT_CRASH”,“ S_EVENT_PLAYER_LEAVE_UNIT”中的事件
还是非常缓慢地谨慎使用它,并始终在参数中首先列出最可能的结果。
优化的第一个查询-
SELECT *
INTO #BlueFlagR2IGC
FROM BlueFlagR2
DELETE FROM #BlueFlagR2IGC
WHERE InitiatorGroupCat != ''
SELECT *
INTO #BlueFlagR2IP
FROM BlueFlagR2
DELETE FROM #BlueFlagR2IP
WHERE InitiatorID = 0
AND InitiatorPlayer = 'No Initiator'
SELECT DeadTbl.TIME AS 'Time',DeadTbl.Event AS 'Event',DeadTbl.InitiatorCoa AS 'Target Coalition',DeadTbl.InitiatorPlayer AS 'Target Player',DeadTbl.InitiatorType AS 'Target Type',DeadTbl.InitiatorGroupCat
,HitTbl.InitiatorCoa AS 'Coalition',HitTbl.InitiatorPlayer AS 'Player',HitTbl.InitiatorType AS 'Type',HitTbl.WeaponCat AS 'Weapon Category',HitTbl.WeaponName AS 'Weapon Name'
FROM (
SELECT TIME,InitiatorID,EVENT,InitiatorCoa,InitiatorType,InitiatorPlayer,InitiatorGroupCat
FROM #BlueFlagR2IGC
WHERE EVENT in ('S_EVENT_DEAD','S_EVENT_CRASH','S_EVENT_PLAYER_LEAVE_UNIT')
) AS DeadTbl
JOIN (
SELECT MAX(`Time`) AS `Time`
,InitiatorID,InitiatorCoa,InitiatorPlayer,InitiatorType
,WeaponCat,WeaponName
,TargetID,TargetCoa,TargetType,TargetPlayer
FROM #BlueFlagR2IP
WHERE EVENT = 'S_EVENT_HIT'
GROUP BY InitiatorID,InitiatorPlayer,TargetID,TargetType
) AS HitTbl ON DeadTbl.InitiatorID = HitTbl.TargetID
AND DeadTbl.InitiatorCoa = HitTbl.TargetCoa
AND DeadTbl.InitiatorPlayer = HitTbl.TargetPlayer
AND DeadTbl.InitiatorType = HitTbl.TargetType
AND HitTbl.TIME <= DeadTbl.TIME
GROUP BY DeadTbl.InitiatorID,DeadTbl.TIME,HitTbl.InitiatorID
ORDER BY DeadTbl.TIME ASC
drop table #BlueFlagR2IGC
drop table #BlueFlagR2IP
优化第二查询:
SELECT *
INTO #BlueFlagR2IGC
FROM BlueFlagR2
DELETE FROM #BlueFlagR2IGC
WHERE InitiatorGroupCat != ''
SELECT *
INTO #BlueFlagR2IP
FROM BlueFlagR2
DELETE FROM #BlueFlagR2IP
WHERE InitiatorID = 0
AND InitiatorPlayer = 'No Initiator'
SELECT *
INTO #BlueFlagR2AI
FROM BlueFlagR2
DELETE FROM #BlueFlagR2AI
WHERE InitiatorPlayer = 'AI'
if OBJECT_ID('tempdb..#target') is not null
drop table #target
SELECT K.Player AS Player, K.Ground AS Ground, K.Airplane AS Airplane, K.Helicopter AS Helicopter, K.Ship AS Ship, K.Total AS Total, IFNULL(D.Total,0) AS Deaths, (CASE WHEN D.Total IS NULL THEN K.Total ELSE K.Total/D.Total END) AS KD_Ratio
INTO #target
FROM
(
SELECT PlayerTable.Player AS 'Player', SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'GROUND_UNIT' THEN 1 ELSE 0 END) AS Ground, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'AIRPLANE' THEN 1 ELSE 0 END) AS Airplane, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'HELICOPTER' THEN 1 ELSE 0 END) AS Helicopter, SUM(CASE WHEN PlayerTable.InitiatorGroupCat = 'SHIP' THEN 1 ELSE 0 END) AS Ship, COUNT(PlayerTable.`Target Player`) AS Total
FROM
(
SELECT DeadTbl.Time AS 'Time', HitTbl.InitiatorCoa AS 'Coalition', HitTbl.InitiatorPlayer AS 'Player', HitTbl.InitiatorType AS 'Type',HitTbl.WeaponCat AS 'Weapon Category',HitTbl.WeaponName AS 'Weapon Name', DeadTbl.Event AS 'Event', DeadTbl.InitiatorCoa AS 'Target Coalition', DeadTbl.InitiatorPlayer AS 'Target Player', DeadTbl.InitiatorType AS 'Target Type', DeadTbl.InitiatorGroupCat
FROM
(
SELECT TIME,InitiatorID,EVENT,InitiatorCoa,InitiatorType,InitiatorPlayer,InitiatorGroupCat
FROM #BlueFlagR2IGC
WHERE EVENT in ('S_EVENT_DEAD','S_EVENT_CRASH','S_EVENT_PLAYER_LEAVE_UNIT')
) AS DeadTbl
JOIN
(
SELECT MAX(`Time`) AS `Time`,InitiatorID,InitiatorCoa,InitiatorPlayer,InitiatorType,WeaponCat,WeaponName,TargetID,TargetCoa,TargetType,TargetPlayer
FROM #BlueFlagR2IP
WHERE EVENT = 'S_EVENT_HIT'
GROUP BY InitiatorID,InitiatorPlayer,TargetID,TargetType
) AS HitTbl
ON DeadTbl.InitiatorID = HitTbl.TargetID AND DeadTbl.InitiatorCoa = HitTbl.TargetCoa AND DeadTbl.InitiatorPlayer = HitTbl.TargetPlayer AND DeadTbl.InitiatorType = HitTbl.TargetType AND HitTbl.Time <= DeadTbl.Time
GROUP BY DeadTbl.InitiatorID,DeadTbl.Time,HitTbl.InitiatorID
) AS PlayerTable
GROUP BY PlayerTable.Player
) AS K
DELETE FROM #target
WHERE Player = 'AI'
AND Player = ''
AND Player = 'No Initiator'
SELECT k.*
FROM #target k
LEFT JOIN
(
SELECT InitiatorPlayer, COUNT(*) AS Total
FROM #BlueFlagR2AI
WHERE EVENT in ('S_EVENT_DEAD', 'S_EVENT_CRASH')
AND InitiatorGroupCat in ( 'AIRPLANE', 'HELICOPTER')
GROUP BY InitiatorPlayer
) AS D
ON K.Player = D.InitiatorPlayer
ORDER BY CASE WHEN KD_Ratio = 'Infinite' THEN K.Total
ELSE KD_Ratio END DESC
drop table #BlueFlagR2IGC
drop table #BlueFlagR2IP
drop table #BlueFlagR2AI
我已经为我的SQL更新了删除表。 我不确定如何在MY SQL中执行此操作。 只要确定,如果我们在查询中使用不等于(!=),将花费更多时间。
我认为真正的问题不在于sql本身,而在于创建数据库的方式。 您正在使用varchars几乎所有内容。 那不是一个好的数据库结构。 您应该为武器,武器类别等创建新表,并创建与这些表的关系。 这就是使用关系数据库的全部要点! :-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.