简体   繁体   English

TEXT列上的MySQL索引无效

[英]MySQL Index on TEXT Column not Effective

I've got a fairly straightforward table for storing key:value pairs, set up like: 我有一个非常简单的表来存储key: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` (`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

...and there are a reasonable number of entries in this table: ...并且此表中有合理数量的条目:

mysql> select count(*) from assetProperties;
+----------+
| count(*) |
+----------+
| 19931305 |
+----------+

...and what I want to do is find entries that exactly match a given key:value pair. ...而我要做的是找到与给定的key:value对完全匹配的条目。 For example, using a query like: 例如,使用如下查询:

SELECT count(*) FROM assetProperties WHERE propertyKey = "Wood Species" 
    AND propertyValue = "Jarrah";

Without any indexes on propertyKey and propertyValue , that query runs quite slowly, like on the order of 10+ seconds. propertyKeypropertyValue上没有任何索引,该查询运行速度非常慢,大约需要10秒钟以上。 Which is to be expected. 这是可以预期的。 The problem is, even after adding indexes on both fields, the query time is not improved. 问题是,即使在两个字段上都添加了索引之后,查询时间也没有得到改善。

The strange thing is, the index on propertyKey appears to be working correctly: 奇怪的是, 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

...while the index on propertyValue appears to have made little difference: ...虽然propertyValue上的索引似乎没有什么区别:

-- Before adding index
mysql> SELECT count(*) FROM assetProperties WHERE propertyValue = "Jarrah";
+----------+
| count(*) |
+----------+
|   219099 |
+----------+
1 row in set (12.51 sec)  <-- bad

-- After adding index
mysql> SELECT count(*) FROM assetProperties WHERE propertyValue = "Jarrah";
+----------+
| count(*) |
+----------+
|   219099 |
+----------+
1 row in set (9.75 sec)  <-- still garbage

The only difference between propertyKey and propertyValue is that the former is a varchar(255) column and the latter is text . propertyKeypropertyValue之间的唯一区别是,前者是varchar(255)列,后者是text Is there something preventing MySQL from making efficient use of the index on the text column, or anything I can do to make the query faster? 是否有某些因素阻止MySQL有效利用text列上的索引,或者我可以做些什么来加快查询速度?

Edit 编辑

Also tried adding a multi-column index across both fields. 还尝试在两个字段之间添加多列索引。 Made no difference. 没什么区别。

And further, if I add a new column (say propertyValueShort ) of type varchar(255) and copy the values from propertyValue into the new column and set up the relevant indexes, it works as it should: 此外,如果我添加类型为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

So that may be the immediate answer (the longest propertyValue currently in use is 88 characters, so I don't really need to be using text there). 因此,这可能是直接的答案(当前使用的最长的propertyValue是88个字符,因此我真的不需要在那里使用text )。 However still doesn't explain why the index on the text column performs so poorly. 但是仍然无法解释为什么 text列上的索引表现如此差。

PRIMARY KEY (`id`),
KEY `keyIndex` (`propertyKey`),

--> - >

PRIMARY KEY(property_key, id),
INDEX(id),

Why? 为什么?

  • InnoDB "clusters" the PK with the data. InnoDB使用数据“聚类” PK。 This means that all rows with the same property_key will now be "next to each other", thereby minimizing disk reads. 这意味着具有相同property_key所有行现在将“彼此相邻”,从而最大程度地减少了磁盘读取。
  • Is id an AUTO_INCREMENT ? idAUTO_INCREMENT吗? If so, INDEX(id) is sufficient; 如果是这样,则INDEX(id)就足够了; PK is not needed. 不需要PK。 Else... Why have id ? 其他...为什么要有id Can you get rid of it? 你能摆脱它吗? Not really; 并不是的; you still need to make the PK unique somehow. 您仍然需要使PK与众不同。

What is the ROW_FORMAT of the table? 该表的ROW_FORMAT是什么? How long is property_value typically? 通常, property_value多长时间? Those impact whether 'big' fields such as TEXT are kept with the row, or stored separately. 这些都会影响“大”字段(例如TEXT)是随行保留还是单独存储。

(Bottom line: key-value schemas suck.) (底线:键值模式很糟糕。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM