2010-12-14 20 views
1

インデックス作成に関して私は迷っています。私はクライアントのために構築しています適度に複雑なWebアプリケーションを持っており、それにはいくつかの数(*)は、すべての非常に遅い実行しているクエリ(0.3秒)複数のカウント(*)クエリのMySQLインデックス

ここ

SELECT COUNT(*) AS `count` 
FROM `vehicles` 
WHERE `VehicleLocation_province` = 'Alberta' 
AND `default_image_URI` IS NOT NULL 
AND `default_image_URI` != '' 

がここにあります簡単な例がありますがあります説明..

1 SIMPLE vehicles ref VehicleLocation_province,VehicleLocation_province_...  VehicleLocation_province 2 const 14128 Using where 

私はできていなくても、適切なインデックスを使用するには、このクエリは、このよう

SELECT * , (6371 * ACOS(COS(RADIANS(53.543564)) * COS(RADIANS(lat)) * COS(RADIANS(lng) - RADIANS(- 113.490456)) + SIN(RADIANS(53.543564)) * SIN(RADIANS(lat)))) AS `distance` 
FROM `vehicles` 
WHERE `Make` = 'Pontiac' 
AND `BodyStyle` = 'Sedan' 
AND `VehiclePrice` >= '1' 
AND `VehiclePrice` <= '36000' 
AND `VehiclePrice` IS NOT NULL 
AND `default_image_URI` IS NOT NULL 
AND `default_image_URI` != '' 
HAVING `distance` < 50 
ORDER BY `VehicleReceivedDate` DESC LIMIT 25 
など、より複雑なクエリのいくつかを気にしないで取得

私は一時テーブルとfilesorts可能性を避けるために必要がある知っている...しかし、どのように、これは事実上どこ変化させてそれぞれのリクエストで実行する必要があり、これらのCOUNT(*)クエリの際には、いくつかの達成さ

1 SIMPLE vehicles ref Make,BodyStyle,VehicleLocation_province_2 Make 99 const 5821 Using where; Using filesort 

を説明パラメータのグループ化と順序付け

+0

このInnoDBまたはMyISAMはありますか?パフォーマンス、インデックス作成、カウント(*)は完全に異なります。 – cherouvim

+0

@cherouvim、確かに彼らは完全に異なっているわけではありません:) - いくつかの一般的なルールはまだ適用されます。 – Unreason

+0

MyISAM。明らかにInnoDBのパフォーマンスに重大な影響を与えます(私が読んだので) – JeremyFelix

答えて

0

私は考えていなかった別のオプション(これは理想的な解決策と見なされています)は、インデックス作成とパフォーマンスに重大な影響を及ぼす場合にSphinxのような検索サーバーを使用することです。スフィンクスはグループ化とカウントだけでなく、いくつかの異なる検索構成で、フルテキストと属性検索/フィルタリングを多数の列で実行できます。

スフィンクスは、複雑な検索クエリを実行しているときには、車輪を再発明してカバーしようとするマルチカラムインデックスのばかげリストで終わるしようとするために、ほとんど意味がないSetGeoAnchor ($attrlat, $attrlong, $lat, $long)

で半径計算に@geodistを行うことができますすべての方法の使用例。

私はプロジェクトの早い段階で検索サーバーを考えていたと思いますが、パフォーマンスに関する問題を解決するには少し遅れています。

http://sphinxsearch.com

2

インデックスを取得する唯一の方法は、選択性が役立つ十分な条件を索引に含めることです(またはRDBMSで索引を使用して集計などの集計を計算できるようにする)。

(BodyStyle)(Make)のインデックスとインデックスを有する(Make, BodyStyle)にインデックスを持つと同じではないことを実現するために失敗しないでください。

最初のクエリでは、レコードをカウントする必要がある場合、default_image_URIVehicleLocation_provinceをカバーするインデックスの存在は、テーブルスキャンを実行せずインデックスからカウントを取得するのに十分なはずです。

インデックス(VehicleLocation_province, default_image_URI)を作成し、クエリを実行したり、説明を調べたりすることで確認できます。

2番目のクエリでは、より多くの条件(すべてAND条件である限り良い)を持つクエリと同様の状況があります。レコードをカウントするのではなく、実際にテーブルからデータを取得して、のソート。ここ

ほとんどのノート:

  • 予告あなたの条件IS NOT NULL!='' - これらの条件は、あなたのクエリに共通して存在している場合、これらは、あなたのデザインが適切でないことを示唆している、とあなたが一つのテーブルに異なるエンティティをdenormalisedしていることデータを使用するたびにそれらを並べ替える必要があります(これは単なる表示に過ぎず、これらの条件を適用すると仮定します)。
  • 2番目のクエリを見て、MakeとBodyStyleがコンポジットiでカバーされている場合ndexと低い選択性を持つクエリは高速で実行されます
  • mysqlはデータにアクセスするために1つのインデックスを選択する必要があり、統計情報と利用可能な条件を指定して行数を返すインデックスを選択しようとしますレコードの最小数をループする) - そのインデックスが結果セットを減らすだけであれば、ソートはfilesortを使用して行われます。上記のクエリインデックスでは、(Make, BodyStyle, VehicleReceivedDate)の場合は、
  • テーブルに適切なインデックスを追加すると役立ちますが、インデックスは修正できませんデザイン上の問題
+0

非常にうまく説明されています。私はあまりにも答えを与えるのではなく、特定のことがどうやって起こるのかを説明したい。 – DRapp

+0

この記事は、MySQLがGROUPでインデックスを使用するために必要な実際の「ルール」の説明に役立ちます。http://dev.mysql.com/doc/refman/5.0/ja/group-by-optimization.html このメモでは、複数のクエリがよりスムーズに実行され、マルチカラムインデックスの順序をより強固に理解しています。 このプロジエクトは、モデルを最適化し、何らかの形でクエリを構造化して、残念ながら、このプロジェクトでは時間がかかるようです。 – JeremyFelix

+0

インデックス+クエリキャッシュは、適切なパフォーマンスでトリックを行っているようです。みんなありがとう。 – JeremyFelix

関連する問題