19

次の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
4

5 に答える 5

29

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

クエリによるグループの最適化については、mysql のマニュアルを参照してください:-最適化によるグループ化

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

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

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

于 2012-04-23T10:37:54.270 に答える
4

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

于 2012-04-23T10:38:19.670 に答える
2

これを試してください:

SELECT distinct CustomerID FROM sales WHERE `Date` <= '2012-01-01'
于 2012-04-23T10:38:41.447 に答える
0

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

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

もちろん、必ずインデックスを配置してくださいDate。完全にはわかりませんが、索引付けCustomerIDも役立つかもしれません。

于 2012-04-23T10:38:07.750 に答える