PRIMARY KEYの最初の部分として、DATETIME(または日付)のインデックス付けに問題があります。
MySQL 5.5を使用します
これが私の2つのテーブルです。
-- This is my standard table with dateDim as a dateTime
CREATE TABLE `stats` (
`dateDim` datetime NOT NULL,
`accountDim` mediumint(8) unsigned NOT NULL,
`execCodeDim` smallint(5) unsigned NOT NULL,
`operationTypeDim` tinyint(3) unsigned NOT NULL,
`junkDim` tinyint(3) unsigned NOT NULL,
`ipCountryDim` smallint(5) unsigned NOT NULL,
`count` int(10) unsigned NOT NULL,
`amount` bigint(20) NOT NULL,
PRIMARY KEY (`dateDim`,`accountDim`,`execCodeDim`,`operationTypeDim`,`junkDim`,`ipCountryDim`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
-- Here is a copy with datDim as an integer
CREATE TABLE `stats_todays` (
`dateDim` int(11) unsigned NOT NULL,
`accountDim` mediumint(8) unsigned NOT NULL,
`execCodeDim` smallint(5) unsigned NOT NULL,
`operationTypeDim` tinyint(3) unsigned NOT NULL,
`junkDim` tinyint(3) unsigned NOT NULL,
`ipCountryDim` smallint(5) unsigned NOT NULL,
`count` int(10) unsigned NOT NULL,
`amount` bigint(20) NOT NULL,
PRIMARY KEY (`dateDim`,`accountDim`,`execCodeDim`,`operationTypeDim`,`junkDim`,`ipCountryDim`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
両方のテーブルにまったく同じデータを入力します(100,000近く)
だが:
- 統計表は、dateDimにDATETIMEを使用します
- stats_todaysは、dateDimにTO_DAYS()でun INTEGERを使用します
私の質問は次のとおりです。なぜインデックスの最初の部分が日時であるときにMySQLが主キーを使用しないのか?同じデータであるがINTEGERとTO_DAYS(dateDim)で統合されているため、同じリクエストが揺れるため、非常に奇妙です。
統計表(および日時)の例:
SELECT *
FROM `stats`
WHERE
dateDim = '2014-04-03 00:00:00'
AND accountDim = 4
AND execCodeDim = 9
AND operationTypeDim = 1
AND junkDim = 5
AND ipCountryDim = 3
=> 1 result (4.5sec)
Explain:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE stats ALL NULL NULL NULL NULL 8832329 Using where
他のテーブルstats_todaysで同じリクエスト(INTEGERおよびTO_DAYS()を使用)
EXPLAIN SELECT *
FROM `stats_todays`
WHERE
dateDim = TO_DAYS('2014-04-03 00:00:00')
AND accountDim = 4
AND execCodeDim = 9
AND operationTypeDim = 1
AND junkDim = 5
AND ipCountryDim = 3
=> Result 1 row (0.0003 sec)
Explain:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE stats_todays const PRIMARY PRIMARY 13 const,const,const,const,const,const 1
投稿全体を読むと、リクエストはINTEGER dateDimフィールドでまったく同じカーディナリティで機能するため、カーディナリティが低い問題ではないことを理解できます。
高度な詳細を次に示します。
SELECT COUNT( DISTINCT dateDim )
FROM stats_todays
UNION ALL
SELECT COUNT( DISTINCT dateDim )
FROM stats;
Result:
COUNT(DISTINCT dateDim)
2192
2192
INDEXの説明は次のとおりです。
SHOW INDEXES FROM `stats`
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
stats 0 PRIMARY 1 dateDim A 6921 NULL NULL BTREE
stats 0 PRIMARY 2 accountDim A 883232 NULL NULL BTREE
stats 0 PRIMARY 3 execCodeDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 4 operationTypeDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 5 junkDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 6 ipCountryDim A 8832329 NULL NULL BTREE
SHOW INDEXES FROM `stats_todays`
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
stats_todays 0 PRIMARY 1 dateDim A 7518 NULL NULL BTREE
stats_todays 0 PRIMARY 2 accountDim A 4022582 NULL NULL BTREE
stats_todays 0 PRIMARY 3 execCodeDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 4 operationTypeDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 5 junkDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 6 ipCountryDim A 8045164 NULL NULL BTREE
SELECT dateDim、COUNT(*)FROM stats GROUP BY dateDim WITH ROLLUP
- 2192の異なる日付があり、再パーティション化がスムーズであることを示しています(日付で約3000-4000行)
- テーブルには8 831 990行あります
- 他のテーブルでも同じ
- COVERING INDEXで試しました(すべてのPK列で*を置き換えます)=>何も変更されませんでした
- force | use index =>何も変更しませんでした
- 日時ではなく日付フィールドでも同じ
- 主キーの代わりにINDEXまたはUNIQUEでも同じ
そして、あなたが走っ
—
ypercubeᵀᴹ
WHERE dateDim = DATE('2014-04-03 00:00:00')
たら?
pkの並べ替えで機能します。しかし、実際には、where句にdateDimとaccountDimのみを使用してリクエストを作成します。私はケーススタディのためのすべてのPKフィールドを使用して...
date
代わりにを使用しても同じことが起こりますdatetime
か?