次の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
(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が集計クエリを計算する方法を完全に理解していなくても、試行錯誤によって有用なインデックスを作成できます。
テーブルスキーマがどのように見えるかを知らなければ、確実にするのは難しいですが、Date
とCustomerID
に複数列のインデックスを追加すると役立つでしょう。これにより、MySQLは_GROUP BY
_ステートメントの全表スキャンを実行する手間を省くことができます。したがって、ALTER TABLE sales ADD INDEX (Date,CustomerID)
を試してください。
これを試してください:
SELECT distinct CustomerID FROM sales WHERE `Date` <= '2012-01-01'
同じ問題が発生しました。キーフィールドを同じ照合順序に変更すると、問題が修正されます。テーブルを結合するフィールドの照合値が異なります。
これははるかに速く、同じことを達成しませんか?
SELECT DISTINCT CustomerID FROM sales WHERE `Date` <= '2012-01-01'
もちろん、必ずDate
にインデックスを付けてください。完全にはわかりませんが、CustomerID
のインデックス作成も役立つ可能性があります。