MySQL:索引附加字段有哪些缺点?

mur*_*lai 3 php mysql indexing

我有这样的知识:

CREATE TABLE  UserTrans (
 `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
   `transaction_id` varchar(255) NOT NULL default '0',
  `source` varchar(100) NOT NULL,
   PRIMARY KEY (`id`),
   KEY `user_id` (`user_id`)
)
Run Code Online (Sandbox Code Playgroud)

与innodb引擎.

transaction_id是var,因为有时它可能是aphanumeric.

id是主键.

所以..这就是事情,我有超过1M的记录.但是,有一个查询要检查指定源上的重复transaciton_id.所以,这是我的查询:

SELECT * 
  FROM UserTrans 
 WHERE transaction_id = '212398043' 
   AND source = 'COMPANY_A';
Run Code Online (Sandbox Code Playgroud)

这个查询变得非常慢,比如现在运行2秒.我应该索引transaction_id和源吗?
例如KEY join_id(transaction_id,source)

如果我这样做有什么缺点?

Bil*_*win 6

显然,好处是它将改善某些查询的性能.

缺点是它需要一些空间来存储索引和RDBMS维护索引的一些工作.索引特别容易占用空间,因为您的transaction_id是一个如此宽的字符串.

您可以考虑transaction_id是否确实需要最多255个字符,或者您是否可以将其最大长度声明为更短.

或者您可以使用前缀索引仅索引前n个字符:

CREATE INDEX join_id ON UserTrans (transaction_id(16), source(16));
Run Code Online (Sandbox Code Playgroud)

@Daniel有一个很好的观点,你可以获得相同的好处,并通过仅索引一列来节省更多空间.既然你正在做,SELECT *你已经排除了覆盖指数的好处.

另外,如果您希望transaction_id是唯一的,为什么不将它限制为唯一?

CREATE UNIQE INDEX uq_transaction_id ON UserTrans (transaction_id(16));
Run Code Online (Sandbox Code Playgroud)


Dan*_*llo 5

主要缺点是新索引会占用磁盘空间.它还会使插入和更新速度稍慢(但在大多数情况下这通常可以忽略不计).

另一方面,您的查询可能只需几毫秒而不是2秒.