【问题标题】:Mysql best index(es) for an agenda table议程表的 Mysql 最佳索引
【发布时间】:2017-09-22 13:59:09
【问题描述】:
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 ;

让我们有这样一种情况:一个软件的议程表有 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声明,然后我可以看看建立最好的索引。
  • 我添加了一些我在工作中看到的例子。
  • 无论您是在执行SELECT * 还是选择几行,这可能都很重要。
  • A SELECT * " 对于内存使用来说是一个糟糕的选择,或者它也会影响查询的速度?
  • 是的,是的。它可能会阻止使用“覆盖”索引。如果您明天添加一列,它可能会弄乱接收SELECT 输出的代码。所有这些批评都可能是次要的。

标签: mysql optimization indexing agenda


【解决方案1】:
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 关于构建索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多