web-dev-qa-db-ja.com

MySQLグループ-非常に遅い

次のSQLクエリがあります

SELECT CustomerID FROM sales WHERE `Date` <= '2012-01-01' GROUP BY CustomerID

クエリは11400000行を超えて実行され、実行速度が非常に遅くなります。実行には3分以上かかります。 group-byパーツを削除すると、1秒未満で実行されます。何故ですか?

MySQLサーバーのバージョンは「5.0.21-community-nt」です

Here is the table schema:
CREATE TABLE `sales` (
  `ID` int(11) NOT NULL auto_increment,
  `DocNo` int(11) default '0',
  `CustomerID` int(11) default '0',
  `OperatorID` int(11) default '0',
  PRIMARY KEY  (`ID`),
  KEY `ID` (`ID`),
  KEY `DocNo` (`DocNo`),
  KEY `CustomerID` (`CustomerID`),
  KEY `Date` (`Date`)
) ENGINE=MyISAM AUTO_INCREMENT=14946509 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
16
Treach

(Date、CustomerID)にインデックスを付けてみてください。

Groupbyクエリを最適化するためのmysqlマニュアルを参照してください。- Group by Optimization

次のようにEXPLAINを使用すると、mysqlがどのように結果を生成しているかを確認できます。-

EXPLAIN SELECT CustomerID FROM sales WHERE `Date` <= '2012-01-01' GROUP BY CustomerID

これにより、mysqlがクエリを最適化するために使用しているインデックス(存在する場合)がわかります。これは、インデックスを作成してmysqlがそれを使用するかどうかを確認できるため、どのインデックスがどのクエリに対して機能するかを学習するときに非常に便利です。したがって、mysqlが集計クエリを計算する方法を完全に理解していなくても、試行錯誤によって有用なインデックスを作成できます。

25
rgvcorley

テーブルスキーマがどのように見えるかを知らなければ、確実にするのは難しいですが、DateCustomerIDに複数列のインデックスを追加すると役立つでしょう。これにより、MySQLは_GROUP BY_ステートメントの全表スキャンを実行する手間を省くことができます。したがって、ALTER TABLE sales ADD INDEX (Date,CustomerID)を試してください。

4
Daan

これを試してください:

SELECT distinct CustomerID FROM sales WHERE `Date` <= '2012-01-01'
2
IT ppl

同じ問題が発生しました。キーフィールドを同じ照合順序に変更すると、問題が修正されます。テーブルを結合するフィールドの照合値が異なります。

これははるかに速く、同じことを達成しませんか?

SELECT DISTINCT CustomerID FROM sales WHERE `Date` <= '2012-01-01'

もちろん、必ずDateにインデックスを付けてください。完全にはわかりませんが、CustomerIDのインデックス作成も役立つ可能性があります。

0