2017-03-08 2 views
-1

db web appのパフォーマンスに問題があります。私はテーブルにインデックスを追加しようとする "時間を得るために"。そしてそれはちょっと働いています。インデックスを使用すると、20秒から3秒の時間が得られますが、問題は持続時間が短縮されてもOKですが、フェッチが0,001から約16秒に増えていますか? 誰かがこのような問題を抱えていましたか?同じ検索データとクエリの10000xFetch時間を得ずにインデックス秒のMysqlと同じquerys 1つ?

時間:

Duration/Fetch    Duration/Fetch 
Orignal query    Query with index  
17.375 sec/0.016 sec 5.047 sec/15.140 sec 27197 row(s) returned 
17.141 sec/0.031 sec 2.047 sec/15.844 sec 32497 row(s) returned 
15.984 sec/0.015 sec 2.938 sec/16.562 sec 19532 row(s) returned 
15.515 sec/0.000 sec 18.406 sec/0.000 sec 91 row(s) returned 
15.906 sec/0.015 sec 5.891 sec/15.390 sec 10278 row(s) returned 



SELECT u.id AS ID 
from urzadzenie u 
LEFT OUTER JOIN przedmiot pr ON u.id = pr.id_urzadzenie AND pr.del = 0 
LEFT OUTER JOIN ozf_przedmiot ozf ON ozf.id_przedmiot = pr.id AND ozf.del = 0 
LEFT OUTER JOIN zamowienie zm ON zm.id = ozf.id_zamowienie AND zm.del = 0 
LEFT OUTER JOIN instalacja_urzadzenia i ON u.id = i.id_urzadzenie AND data_usuniecia IS NULL 
LEFT OUTER JOIN lokalizacja_urzadzenia lu ON lu.id = i.id_lokalizacja 
LEFT OUTER JOIN obiekt o ON i.id_obiekt = o.id 
LEFT OUTER JOIN podmiot p ON o.id_podmiot = p.id,wersja_urzadzenia w, typ_urzadzenia t,kategoria_urzadzenia k 
LEFT OUTER JOIN urzadzenie_uwagi uuw ON uuw.id = (select max(id) from urzadzenie_uwagi uw WHERE uw.del = 0 AND uw.id_urzadzenie = u.id AND uw.id_urzadzenie_uwagi_rodzaj in (1,2,3,11,12,13)) 
WHERE ((UPPER(k.nazwa) LIKE UPPER('%SomeName%') OR UPPER(t.nazwa) LIKE UPPER('%SomeName%') 
    OR UPPER(concat(t.nazwa, '-', w.nazwa)) LIKE UPPER('%SomeName%') OR UPPER(u.nr_ewidencyjny) LIKE UPPER('%SomeName%') 
    OR UPPER(u.nr_ewidencyjny2) LIKE UPPER('%SomeName%') OR UPPER(p.nazwa) LIKE UPPER('%SomeName%') 
    OR UPPER(lu.opis) LIKE UPPER('%SomeName%') OR UPPER(u.data_produkcji) LIKE UPPER('%SomeName%'))) 
    AND(u.del = 0 AND u.id_wersja = w.id AND w.id_typ = t.id AND t.id_kategoria = k.id) 
ORDER BY ID DESC; 


SELECT u.id AS ID 
from urzadzenie u use index(part_of_name5) 
LEFT OUTER JOIN przedmiot pr ON u.id = pr.id_urzadzenie AND pr.del = 0 
LEFT OUTER JOIN ozf_przedmiot ozf use index(part_of_name1) ON ozf.id_przedmiot = pr.id AND ozf.del = 0 
LEFT OUTER JOIN zamowienie zm ON zm.id = ozf.id_zamowienie AND zm.del = 0 
LEFT OUTER JOIN instalacja_urzadzenia i ON u.id = i.id_urzadzenie AND data_usuniecia IS NULL 
LEFT OUTER JOIN lokalizacja_urzadzenia lu ON lu.id = i.id_lokalizacja 
LEFT OUTER JOIN obiekt o ON i.id_obiekt = o.id LEFT OUTER JOIN podmiot p ON o.id_podmiot = p.id,wersja_urzadzenia w, typ_urzadzenia t,kategoria_urzadzenia k 
LEFT OUTER JOIN urzadzenie_uwagi uuw ON uuw.id = (select max(id) from urzadzenie_uwagi uw WHERE uw.del = 0 AND uw.id_urzadzenie = u.id AND uw.id_urzadzenie_uwagi_rodzaj in (1,2,3,11,12,13)) 
WHERE ((UPPER(k.nazwa) LIKE UPPER('%SomeName%') OR UPPER(t.nazwa) LIKE UPPER('%SomeName%') 
    OR UPPER(concat(t.nazwa, '-', w.nazwa)) LIKE UPPER('%SomeName%') OR UPPER(u.nr_ewidencyjny) LIKE UPPER('%SomeName%') 
    OR UPPER(u.nr_ewidencyjny2) LIKE UPPER('%SomeName%') OR UPPER(p.nazwa) LIKE UPPER('%SomeName%') 
    OR UPPER(lu.opis) LIKE UPPER('%SomeName%') OR UPPER(u.data_produkcji) LIKE UPPER('%SomeName%'))) 
    AND(u.del = 0 AND u.id_wersja = w.id AND w.id_typ = t.id AND t.id_kategoria = k.id) 
ORDER BY ID DESC; 
+0

どのバージョンのMySQLですか? "duration"が最初の行が返されるまでの時間量である場合、 "duration"と "fetch"の結果は、SQL Serverの 'FIRST 1' /' FASTFIRSTROWS'またはOracle 'FIRST_ROWS'の動作と一貫しています。余りです。 MySQLがORDER BYを満たすためにソート操作を実行しなければならない場合、MySQLは "最初"に返される行を知るために "duration"を長く設定する必要があります。 ORDER BYをソートではなくインデックスで満たすことができれば、MySQLは(理論上)すべての行にアクセスする前に「最初の」行を返すことができます。 – spencer7593

+0

私は、2番目のクエリでは、MySQLが "Using filesort"オペレーションではなく、ORDER BYをインデックスで満たすと考えています。その疑問を「EXPLAIN」からの出力を調べることで確認できました。また、2番目のクエリでは、MySQLが行を見つけたときにそれを返すようになっていると考えています。私は、クエリが終了していないと思う、それはまだ最初の行を返した後に行にアクセスしている。最初のクエリでは、MySQLオプティマイザはすべての行にアクセスした後、並べ替えを実行してから行を返すことが全体的に高速になると判断しています。 – spencer7593

答えて

0
OR UPPER(lu.opis) LIKE UPPER('%SomeName%') 

は3つのパフォーマンスの問題があります。

  • ORは十分に最適化されています。基本的には、テーブルをスキャンしてすべての行をチェックする必要があります。インデックスは役に立たないでしょう。
  • UPPER(indexed-column)この列のインデックスを使用できません。これは、その列を「大文字と小文字を区別しない」COLLATIONというように宣言すると簡単に処理されます。つまり、utf8_unicode_ciのようなものです。 _ciに注意してください。
  • LIKE '%...の先頭にワイルドカードが含まれているため、インデックスを使用できません。また

は、あなたがその多くの行をどうするつもりです

32497 row(s) returned 

を持っていることは通常愚かなのですか?クエリ自体がそうでなくても、ネットワーク転送時間は重要です。

LIKEOR、、およびUPPERの問題を一度に解決するには、テキストをまとめて1つの表の1つの列にまとめます。次に、その列にFULLTEXTの索引を付けます。 は、少なくともSomeName検索を実行すると、より高速に動作します。 (LEFT JOINsは別の問題です)

+0

さらに、なぜフェッチ時間が長くなっているのですか(クエリ時間の減少)、選択されたデータ数は増加しませんでした。 – wronek

+0

"フェッチ"と "クエリ"をどのように測定しているか説明してください。 –

+0

私はmysqlのworkbenchといくつかの他のSQLツールから時間を得る。 – wronek

関連する問題