2015-10-09 3 views
1

Я ищу помощь в оптимизации запросов и понимание того, как это сделать в будущем.Оптимизация запросов SQL/PHP

У меня есть БД на экспорт для легкого использования - 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

До сих пор я пытался сделать ome, добавив индексы и уменьшив выбранные столбцы, но не получив большого эффекта. Я не уверен, как изменить эти большие запросы, чтобы сделать ту же процедуру, но оптимизирован.

First query-

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 

Они в основном похожи, как ядро ​​этого является то же самое.

Цените любую помощь!

+0

Многие из этих подзапросов, вероятно, уничтожают любые преимущества индексации, которые могут дать вам. Попробуйте переписать их без них; в качестве примера, в первом запросе эти две таблицы, вероятно, могут быть подключены напрямую, а их отдельные ГДЕ объединяются. – Uueerdo

+4

Первым шагом для проверки любого запроса, который нуждается в оптимизации, должно быть сделать [EXPLAIN] (https://dev.mysql.com/doc/refman/5.6/en/explain.html) в этом запросе, чтобы увидеть, как база данных выполняет и какие индексы используются –

+1

Это для Microsoft SQL Server или MySQL? Вы отметили этот вопрос тем и другим. –

ответ

0

Вы также используя или, где вы можете быть в состоянии использовать в

ГДЕ EVENT в ('S_EVENT_DEAD', 'S_EVENT_CRASH', '') S_EVENT_PLAYER_LEAVE_UNIT

Или очень медленно использует его сдержанно и всегда перечисляет наиболее вероятный результат сначала в аргументах.

+0

Я попробую это и сообщит – Morrtz

+0

недостаточно оптимизированным, используя это. – Morrtz

0

Оптимизированный Первый query-

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 

я обновил для таблицы капли для MY SQL. Я не уверен, как это сделать в MY SQL. Просто уверен, что если мы используем не равные (! =) Запросы, потребуется больше времени.

+0

Это MySQL, я думаю, поэтому ваши методы здесь не работают? Код ошибки: 1064 У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего MySQL-сервера, для правильного синтаксиса для использования рядом с 'if OBJECT_ID (' tempdb .. # BlueFlagR2IGC ') не является нулевым drop table # BlueFlagR2IGC ' в строке 1 – Morrtz

0

Я думаю, что реальная проблема не в самом sql, а в том, как вы создали базу данных. вы используете varchars практически для всего. Это не хорошая структура базы данных. Вы должны создать новые таблицы для оружия, оружия и т. Д. ... и создать отношения с этими таблицами. В этом весь смысл использования реляционной базы данных! :-)

+0

Хорошо, я получаю вашу мысль. Вы имеете в виду создавать таблицы категорий с PK, которые будут указывать соответствующую информатику, а не хранить все в 1 таблице. Пойду, если я начну это делать. – Morrtz

+0

@Morrtz - да точно. Еще одна вещь заключается в том, что «оптимизировать» это не на самом деле не создает sql для базы данных WHOLE, а просто ограничивает ее до 10 строк (если вы используете страничную загрузку следующей страницы с помощью ajax) – bestprogrammerintheworld

Смежные вопросы