2013-08-27 69 views
1

我有一个帖子表,列id (INT, primary key), name(VARCHAR), status(TINYINT)。该职位的状态可以是1, 2, 3 or 4。比方说,我想选择状态为2的帖子。我如何优化表以获得快速查询,因为为状态字段添加索引不会有太大的帮助。tinyint列优化mysql

我使用mysql 5.5。引擎可以是innodbmyisam

感谢

更新评论

据我了解指数是如何工作的,是当我们添加索引它有点创建列,但在一个有序的方式复制 - 数字(或文本 - 按字母顺序),所以它提供了二进制搜索的可能性。所以,如果我们需要找到某个值,我们可以避免对表格进行全面扫描。但在这种情况下,假设我的表格中有100K行,并且有大致的说法 - 等于行数1, 2, 3 and 4。如果我为该字段添加索引,毕竟它应该对剩余的25k行进行线性搜索,并且如果我们考虑到添加索引会降低插入和更新速度,可能不值得。

查询 - SELECT id, name FROM posts WHERE status = 2

+3

为什么不为状态字段添加索引帮助那么大? – bumperbox

+0

为什么添加索引不会加快查询速度?你在做什么类型的查询?请举个例子。 – Ander2

+1

分成4个表格! –

回答

2

如何以及索引工作在这种情况下取​​决于两个因素。这里有三种情况,索引可以很好地工作(第三次感谢Vatev)。

第一个是当状态2的记录很少的时候。比如说,你有一个有100万条记录的表,并且在任何给定的时间只有100个记录具有状态2。索引将帮助您找到它们。

第二种情况是status是表上的主键(或者至少是主键中的第一列)。这将任何表扫描限制为status = 2仅限于表的一部分。当然,拥有状态主键会使状态的后续更新更加昂贵,因为必须根据状态值重新定位数据。

第三种情况是当status - 或索引中包含status - 的列是覆盖索引时。这意味着查询所需的所有列都位于索引中,因此引擎不必查找原始数据页面。

一般来说,我建议对低基数字段的索引。这是一条通用规则,但有些情况下这样的指数可以提高业绩。

+0

第二种情况也适用于使用以状态开头的覆盖索引的查询。 – Vatev

+0

@Vatev。 。 。优秀点。我修改了答案以包含这一点。 –

+0

@戈登林诺夫,我更新了这个问题。谢谢 – dav

2

我不知道你的应用程序或SQL要求

你可以分批不使用限制,因为没有有效的桌子上数以百万计关记录,因为它会创建一个(硬盘/内存)的临时接他们表如果你这样查询。

SELECT id, name FROM posts WHERE status = 2 LIMIT 1000000, 1000000 

如果您解释一下上面的查询你西港岛线看到它会扫描200万行,将使用(硬盘/内存)临时表中,最糟糕的情况下,它需要一个基于磁盘如果内存已满

更好的办法是使用基于你的状态的位置(确保指数)

SELECT id, name FROM posts WHERE status = 2 and position >= 1 and <= 1000000 
SELECT id, name FROM posts WHERE status = 2 and position >= 1000001 and <= 2000000 
... 
... 

真正的低基数的域真的不应该索引的更好的办法是,也许你可以用LIST分区,以获得更多的测试性能,但它仍然需要一个完整的“表(分区)“扫描

查看http://sqlfiddle.com/#!2/d947c/7查看示例并查看EXPLAIN PARTITIONS语句以查看WHERE状态= 1时将只使用partition_post_status_id_1。

或者看到覆盖索引方法http://sqlfiddle.com/#!2/20b0d/1与分区

而且querys涉及聚合函数,如SUM()和COUNT()可以运行并行化的划分,以获得更高的性能自动

0

如果你的要求是真的经常会遇到这种类型的查询,并获取整个表的1/4,我建议你换表使用InnoDB引擎和主键(status, id)

CREATE TABLE posts 
(id INT, 
    name VARCHAR (whatever), 
    status TINYINT, 
    PRIMARY KEY (status, id), 
    UNIQUE INDEX (id) 
) ENGINE = InnoDB ; 

这样,您仍然拥有(id)唯一的聚簇索引(InnoDB默认选择为主键)首先基于status,因此您想要的数据将以WHERE status = @X的顺序存储在磁盘上。