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

时间:2010-09-16 02:42:06

标签: 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`)
)

使用innodb引擎。

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

id是主键。

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

SELECT * 
  FROM UserTrans 
 WHERE transaction_id = '212398043' 
   AND source = 'COMPANY_A';

这个查询变得非常慢,比如现在运行2秒。我应该索引transaction_id和来源吗?
例如KEY join_idtransaction_idsource

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

4 个答案:

答案 0 :(得分:6)

显然,好处是它可以提高某些查询的性能。

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

您可能会考虑transaction_id是否真的需要最多255个字符,或者您是否可以声明其最大长度更短。

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

CREATE INDEX join_id ON UserTrans (transaction_id(16), source(16));

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

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

CREATE UNIQE INDEX uq_transaction_id ON UserTrans (transaction_id(16));

答案 1 :(得分:5)

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

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

答案 2 :(得分:1)

添加索引的缺点是空间(因为存储索引会占用空间)和插入时间(因为当您插入新记录时,必须将它们添加到索引中)。

也就是说,您可能不需要将两个字段编入索引 - 只需将其中一个字段编入索引即可。

答案 3 :(得分:1)

我会想到你的id列,并使用transaction_id作为你的主键 我假设transaction_id是唯一的。

这意味着您的架构会阻止您插入已存在的事务ID。

这减少了存储的数据量,也减少了需要编制索引的列数。

如果source company和transaction_id实际上是一个复合键..我会将这两列作为主键。

您当前的架构允许您放入重复项,这是一种不必要的恶意。