文本列上的MySQL索引无效
我有一个相当简单的表来存储键:值对,设置如下:文本列上的MySQL索引无效,mysql,indexing,query-optimization,entity-attribute-value,Mysql,Indexing,Query Optimization,Entity Attribute Value,我有一个相当简单的表来存储键:值对,设置如下: CREATE TABLE `assetProperties` ( `propertyKey` varchar(255) NOT NULL, `propertyValue` text NOT NULL, `id` bigint(20) NOT NULL, `assetInstance_id` bigint(20) NOT NULL, PRIMARY KEY (`id`), KEY `FK67F768435C68E1C0` (`
CREATE TABLE `assetProperties` (
`propertyKey` varchar(255) NOT NULL,
`propertyValue` text NOT NULL,
`id` bigint(20) NOT NULL,
`assetInstance_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK67F768435C68E1C0` (`id`),
KEY `FK67F76843FBDFC83F` (`assetInstance_id`),
KEY `keyIndex` (`propertyKey`),
KEY `valIndex` (`propertyValue`(255)),
CONSTRAINT `FK67F76843FBDFC83F` FOREIGN KEY (`assetInstance_id`) REFERENCES `assets` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
…此表中有合理数量的条目:
mysql> select count(*) from assetProperties;
+----------+
| count(*) |
+----------+
| 19931305 |
+----------+
…我要做的是找到与给定的键:值对完全匹配的条目。例如,使用如下查询:
SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species"
AND propertyValue = "Jarrah";
在propertyKey
和propertyValue
上没有任何索引,该查询运行非常缓慢,大约10秒以上。这是意料之中的。问题是,即使在两个字段上都添加了索引,查询时间也没有提高
奇怪的是,propertyKey
上的索引似乎工作正常:
-- Before adding index
mysql> SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species";
+----------+
| count(*) |
+----------+
| 339395 |
+----------+
1 row in set (9.37 sec) <-- bad
-- After adding index
mysql> SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species";
+----------+
| count(*) |
+----------+
| 339395 |
+----------+
1 row in set (0.16 sec) <-- reasonable
propertyKey
和propertyValue
之间的唯一区别在于前者是varchar(255)
列,后者是text
。是否有什么东西阻止MySQL有效地使用text
列上的索引,或者我可以做些什么来加快查询速度
编辑
还尝试在两个字段中添加多列索引。没什么区别
此外,如果我添加一个varchar(255)
类型的新列(比如propertyValueShort
),并将propertyValue
中的值复制到新列中并设置相关索引,它的工作原理如下:
mysql> SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species" AND propertyValueShort = "Jarrah";
+----------+
| count(*) |
+----------+
| 219099 |
+----------+
1 row in set (0.14 sec) <-- acceptable
mysql>从资产属性中选择count(*),其中propertyKey=“Wood Species”和propertyValueShort=“Jarrah”;
+----------+
|计数(*)|
+----------+
| 219099 |
+----------+
一行一组(0.14秒)
-->
为什么?
- InnoDB使用数据“集群”PK。这意味着具有相同
属性\u键的所有行现在将“彼此相邻”,从而最大限度地减少磁盘读取
id
是否为自动增量
?如果是这样,索引(id)
就足够了;PK是不需要的。其他的为什么有id
?你能摆脱它吗?不是真的;您仍然需要以某种方式使PK独一无二
表格的行格式是什么?属性值通常需要多长时间?这些影响诸如文本之类的“大”字段是与行一起保存还是单独存储
(底线:键值。)
-->
为什么?
- InnoDB使用数据“集群”PK。这意味着具有相同
属性\u键的所有行现在将“彼此相邻”,从而最大限度地减少磁盘读取
id
是否为自动增量
?如果是这样,索引(id)
就足够了;PK是不需要的。其他的为什么有id
?你能摆脱它吗?不是真的;您仍然需要以某种方式使PK独一无二
表格的行格式是什么?属性值通常需要多长时间?这些影响诸如文本之类的“大”字段是与行一起保存还是单独存储
(底线:键值模式。)您可以发布这些查询的解释输出吗?您可以发布这些查询的解释输出吗?
mysql> SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species" AND propertyValueShort = "Jarrah";
+----------+
| count(*) |
+----------+
| 219099 |
+----------+
1 row in set (0.14 sec) <-- acceptable
PRIMARY KEY (`id`),
KEY `keyIndex` (`propertyKey`),
PRIMARY KEY(property_key, id),
INDEX(id),