-1

結果が返されない限り、完璧に高速に実行されるSQLクエリに問題があります。

私は4つのテーブルを持っています:worlds(2アイテム)、players(約2000アイテム)、world_chunk(約16000アイテム)、world_block(約100万アイテム)

 SELECT bid,playername FROM worlds 
 JOIN world_chunks ON worlds.id = world_chunks.mainid 
 JOIN world_blocks ON world_chunks.cid = world_blocks.cid 
 JOIN players ON world_blocks.player = players.pid 
 WHERE worldname='world' AND x='-684' AND y='63' AND z='-2234' AND cx ='-43' AND cz='-140'

x、y、zはworld_blocksに保持され、cx、czはworld_chunksに保持され、worldnameはworldsに保持されます。すべてのインデックスが設定され、空の結果を除くすべてに対して非常に高速です。

とにかく私は空の結果をスピードアップすることができますか?

皆さんの助けに感謝します。

編集:これがdb構造です:http: //pastebin.com/rxQQ5mzp

そのMySQLInnoDB

EXPLAIN on Emtpy Query:
1   SIMPLE  worlds  ALL PRIMARY,idx_mainid  NULL    NULL    NULL    2      Using where
1   SIMPLE  world_blocks    ALL NULL    NULL    NULL    NULL    766845  Using where; Using join buffer
1   SIMPLE  world_chunks    eq_ref  PRIMARY,idx_cid PRIMARY 4   WatchBlock.world_blocks.cid 1   Using where
1   SIMPLE  players eq_ref  PRIMARY,idx_pid PRIMARY 4   WatchBlock.world_blocks.player  1   

EXPLAIN on Found Query:
1   SIMPLE  worlds  ALL PRIMARY,idx_mainid  NULL    NULL    NULL    2   Using where
1   SIMPLE  world_blocks    ALL NULL    NULL    NULL    NULL    766845  Using where; Using join buffer
1   SIMPLE  world_chunks    eq_ref  PRIMARY,idx_cid PRIMARY 4   WatchBlock.world_blocks.cid 1   Using where
1   SIMPLE  players eq_ref  PRIMARY,idx_pid PRIMARY 4   WatchBlock.world_blocks.player  1 

x、y、zとcx、czが一致しないため、結果は空になる可能性があります(したがって、これらのそれぞれの1つがdbにない場合、プレーヤーの結果は空である必要があります)

4

1 に答える 1

0

Philwinkleは正しいです。適切な説明を投稿せずに、SQLクエリのパフォーマンスに関する質問を投稿することは特に適切ではありません。また、4つのテーブルと関連するインデックスのDDLも投稿しておく必要があります。「すべてのインデックスが設定されています」と言いますが、フォローコメントでは、主キーにあるインデックスのみを使用していることを示唆しています。これは、問題のあるクエリには不十分です。

パフォーマンスの問題については、使用しているデータベースと使用しているテーブルタイプをメモしておくことも役立ちます。タグはこれがmysqlであることを示しています。つまり、myisamとinnodbは提供できない重要な情報です。最後に、「空の」結果は遅いと主張しますが、空の結果が空である理由、結合の1つが空であるため、または座標の1つが一致しなかったために空である理由を説明していません(そうであれば、 world_block、またはworld_chunk座標)。

EXPLAINデータと基本的なDDLを提供した場合、質問はこれまでに回答されている可能性が高いため、これを作成することはありません。現状では、あなたがそうするまで、この質問に合理的に答えることはできません。

私が提供できる最善の方法は、おそらく(x、y、z)および(cx、​​cy)座標の一部またはすべてをカバーする少なくとも1つのインデックスを追加する必要があることです。しかし、それは単なる知識に基づく推測です。

編集:

EXPLAINをありがとう、それは助けになります。すでにお気づきのことと思いますが、world_blocksの全表スキャンが原因である可能性が最も高いです。データベースのサイズが小さいことを考えると、追加したインデックス(cid、x、y、z)がおそらく最も役に立ちました。ただし、他のいくつかのポイント:

これが取り込み+読み取りデータベースである場合は、MyISAMが妥当な選択ですが、オンラインのUPDATEまたはDELETE操作を実行する場合は、InnoDBを使用する方がはるかに優れています。InnoDBの真の利点は、参照整合性よりも並行性/スケーラビリティーが向上することです(ただし、その重要性を過小評価してはなりません)。

このクエリでx、y、zが常に一定である場合は、それらをインデックスの先頭に移動することを検討する必要があります。実際、InnoDBを使用している場合、このEXPLAINは、cidを含めるとバッファキャッシュのみが無駄になるため、インデックスは(x、y、z)だけにある必要があることを示しています。MyISAMの使用を主張する場合は、結合によって参照されるフィールド(x、y、z、cid、players)にカバーリングインデックスを使用することを確実に検討する必要があります。これにより、最終的なプロジェクションまで全行の読み取りが妨げられます。

これが私の最後のポイントです。説明のつかないパフォーマンスの癖に気づいたら、すぐにEXPLAINを実行してください。原因不明のパフォーマンスの癖がなくなった後は、必ずEXPLAINを実行し、それが理にかなっていることを確認してください。MyISAMとInnoDBのインデックスの動作はほとんどの場合異なり、一方の最適化が他方の最適化とは限りません。

于 2012-06-14T04:43:11.230 に答える