Mysql 议程的最佳索引 table
Mysql best index(es) for an agenda table
CREATE TABLE IF NOT EXISTS `agenda` (
`id_agenda` int(11) NOT NULL AUTO_INCREMENT,
`id_user` int(11) NOT NULL DEFAULT '0',
`id_customer` int(11) DEFAULT NULL,
`type` int(11) NOT NULL DEFAULT '8',
`title` varchar(255) NOT NULL DEFAULT '',
`text` text NOT NULL,
`start_day` date NOT NULL DEFAULT '0000-00-00',
`end_day` date NOT NULL DEFAULT '0000-00-00',
`start_hour` time NOT NULL DEFAULT '00:00:00',
`end_hour` time NOT NULL DEFAULT '00:00:00'
PRIMARY KEY (`id_agenda`),
KEY `start_day` (`start_day`),
KEY `id_customer` (`id_customer`),
KEY `id_user` (`id_user`),
KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
让我们有这种情况:一个有议程的软件 table 有 200 万条记录,10 个活跃用户。
支持这种需求的最佳索引配置是什么:
1) 一个用户所有约会的列表。
示例:
SELECT * from agenda where id_user = '1';
2) 一天、一周或一个月的所有约会的列表。
示例:
SELECT * from agenda where start_day = CURDATE();
3) 链接到客户 X 的所有约会的列表。
示例:
SELECT * from agenda where id_customer = 'X';
4) 例如一个月内所有 Y 类型约会的列表。
示例:
SELECT * from agenda where type='2' AND MONTH(start_day) = MONTH(CURDATE());
5) 标题中具有某种字符串模式的所有约会的列表。
示例:
SELECT * from agenda where title LIKE '% closing %';
我问这个是因为我读过很多文档,对于 WHERE 子句、ORDER BY、GROUP BY 中使用的每个字段都有一个索引是一个糟糕的选择,但是对于这种需要如何避免每个字段的索引?
使用复合索引,如果我做对了,我可以使用第二个字段,就像我使用索引的第一个字段一样,对吗?
感谢大家。
SELECT * from agenda where id_user = '1';
INDEX(id_user)
SELECT * from agenda where start_day = CURDATE();
INDEX(start_day)
SELECT * from agenda where id_customer = 'X';
INDEX(id_customer)
这个
SELECT *
from agenda
where type='2'
AND MONTH(start_day) = MONTH(CURDATE());
不是一个好的表述。更改为
SELECT *
from agenda
where type='2'
AND start_day >= CONCAT(LEFT(CURDATE(), 7), '-01')
AND start_day < CONCAT(LEFT(CURDATE(), 7), '-01') + INTERVAL 1 MONTH;
并添加此复合索引:INDEX(type, start_day)
。也去掉 type
上的索引;会没用的。
这个无法按原样优化(因为前导通配符):
SELECT *
from agenda
where title LIKE '% closing %';
然而 FULLTEXT(title)
索引与 MATCH(title) AGAINST('+closing' IN BOOLEAN MODE)
一起会很快。
More 关于建立索引。
CREATE TABLE IF NOT EXISTS `agenda` (
`id_agenda` int(11) NOT NULL AUTO_INCREMENT,
`id_user` int(11) NOT NULL DEFAULT '0',
`id_customer` int(11) DEFAULT NULL,
`type` int(11) NOT NULL DEFAULT '8',
`title` varchar(255) NOT NULL DEFAULT '',
`text` text NOT NULL,
`start_day` date NOT NULL DEFAULT '0000-00-00',
`end_day` date NOT NULL DEFAULT '0000-00-00',
`start_hour` time NOT NULL DEFAULT '00:00:00',
`end_hour` time NOT NULL DEFAULT '00:00:00'
PRIMARY KEY (`id_agenda`),
KEY `start_day` (`start_day`),
KEY `id_customer` (`id_customer`),
KEY `id_user` (`id_user`),
KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
让我们有这种情况:一个有议程的软件 table 有 200 万条记录,10 个活跃用户。
支持这种需求的最佳索引配置是什么:
1) 一个用户所有约会的列表。
示例:
SELECT * from agenda where id_user = '1';
2) 一天、一周或一个月的所有约会的列表。
示例:
SELECT * from agenda where start_day = CURDATE();
3) 链接到客户 X 的所有约会的列表。
示例:
SELECT * from agenda where id_customer = 'X';
4) 例如一个月内所有 Y 类型约会的列表。
示例:
SELECT * from agenda where type='2' AND MONTH(start_day) = MONTH(CURDATE());
5) 标题中具有某种字符串模式的所有约会的列表。
示例:
SELECT * from agenda where title LIKE '% closing %';
我问这个是因为我读过很多文档,对于 WHERE 子句、ORDER BY、GROUP BY 中使用的每个字段都有一个索引是一个糟糕的选择,但是对于这种需要如何避免每个字段的索引? 使用复合索引,如果我做对了,我可以使用第二个字段,就像我使用索引的第一个字段一样,对吗?
感谢大家。
SELECT * from agenda where id_user = '1';
INDEX(id_user)
SELECT * from agenda where start_day = CURDATE();
INDEX(start_day)
SELECT * from agenda where id_customer = 'X';
INDEX(id_customer)
这个
SELECT *
from agenda
where type='2'
AND MONTH(start_day) = MONTH(CURDATE());
不是一个好的表述。更改为
SELECT *
from agenda
where type='2'
AND start_day >= CONCAT(LEFT(CURDATE(), 7), '-01')
AND start_day < CONCAT(LEFT(CURDATE(), 7), '-01') + INTERVAL 1 MONTH;
并添加此复合索引:INDEX(type, start_day)
。也去掉 type
上的索引;会没用的。
这个无法按原样优化(因为前导通配符):
SELECT *
from agenda
where title LIKE '% closing %';
然而 FULLTEXT(title)
索引与 MATCH(title) AGAINST('+closing' IN BOOLEAN MODE)
一起会很快。
More 关于建立索引。