2017-02-24 11 views
-1

私はいくつかの値を取得するためにSUMコマンドを使用するプロジェクトに取り組んでいます。さて、これはうまくいきますが、クエリが完了するまでに3.4秒かかりますので、時間がかかると問題が発生します。ここでMySQL - ネストされたフィールドの選択WHERE

は、私がこれまで持っているものの一例である:そのフィールドはLEFTを使用することによって取得される4.

SELECT 
p.`player_id`, 
p.`player_name` AS `name`, 
d.`player_debut` AS `debut`, 
SUM(a.`player_order` <= '11' OR a.`player_sub` != '0') AS `apps`, 
SUM(a.`player_order` <= '11') AS `starts`, 
SUM(a.`player_goals`) AS `goals` 
FROM 
`table1` r, 
`table2` a, 
`table3` p 
LEFT JOIN `table4` d ON p.`player_id` = d.`player_id` 
WHERE 
r.`match_id` = a.`match_id` AND 
a.`player_id` = p.`player_id` AND 
r.`void` = '0' 
GROUP BY 
a.`player_id` 
ORDER BY 
p.`player_name` ASC 

はラインにあなたの心をキャストクエリのさらに下に登録しよう。これらの2本のラインを取り除くことで、ロード時間が0.5秒未満に短縮されます。

私がそこで達成しようとしていること(4行目)は、成功しないと、見えないWHERE句の種類が適用されている行5-7と似ています。

アイデアはt4.date WHERE t2.order <= '14'ですが、私は前述のLEFT JOINと負荷時間が増えることなく、これを動作させる方法がわかりません。

説明のために、table4がどのように作成されたかを次のクエリで確認します。基本的に

SELECT a.`player_id`, m.`date` AS `player_debut` 
FROM 
`table1` r, 
`table2` a, 
`table3` p 
WHERE 
a.`match_id` = m.`match_id` AND 
a.`player_id` = p.`player_id` AND 
m.`match_void` = '0' AND 
(
    a.`player_order` BETWEEN '1' AND '11' OR 
    a.`player_sub_on_for` != '0' 
) 
GROUP BY p.`player_id` 
ORDER BY p.`player_name` ASC 

、私は両方のクエリで同じテーブルを利用して、唯一異なるWHERE句を利用していますように、私は「巣」これをする方法があるかどうかを確立しようとしています。

+0

http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple- sql-query – Strawberry

+0

情報が 'table4'にある場合は、このテーブルを' FROM'節に置く必要があります(またはサブクエリによって処理されます。おそらくplanner/executorによってまったく同じように扱われますDBMSの)。つまり、これを避けることはできません。あなたは、適切な 'インデックスがあることを確認する必要があります...それはあなたができる最高のものです。 – joanolo

+0

各フィールドのデータベースインデックスを作成してください.https://dev.mysql.com/doc/refman/5.7/en/create-index.html – Tony

答えて

0

あなただけ

SELECT p.`player_id`, p.`player_name` AS `name`, 
min(case when a.player_order <= '11' OR a.`player_sub` != '0' then r.date else 0 end) `debut`, 
SUM(case when a.`player_order` <= '11' OR a.`player_sub` != '0' then 1 else 0 end) AS `apps`, 
SUM(case when a.`player_order` <= '11' then 1 else 0 end) AS `starts`, 
SUM(a.`player_goals`) AS `goals` 
FROM 
`table1` r, 
left join `table2` a on r.`match_id` = a.`match_id`, 
left join `table3` p on a.`player_id` = p.`player_id` 
WHERE r.`void` = '0' 
GROUP BY p.player_id,a.`player_id` 
ORDER BY p.player_id,p.`player_name`; 

条件付きの集約が必要な場合があり、あなたの列名でいくつかの矛盾があるように思われる(。player_sub、。player_sub_on_for、M。match_void、R。void = '0')ので、Iこれはかなり正しいとは言えませんし、集約のないグループバイセクションは無意味です。

+0

すばらしい。元のクエリのすべてが同じままですが、私は自分のコードの第4行をあなたが提供した2行目の代替バージョンに置き換えることができます。 IF ELSEの代わりに、次のように使用して、要件が満たされるまでCASE文がループし続けるようにしました。 '{MIN(a.player_order <= '11' OR a.player_sub!= '0' THEN r.date END)デビュー}' –

+0

MINコマンドを使用すると、LEFT JOIN主なものは、クエリを遅くする。 3.4秒から0.3秒以下になりました。 –

関連する問題