Mysql 使用覆盖索引选择某一天的记录

Mysql 使用覆盖索引选择某一天的记录,mysql,performance,datetime,indexing,Mysql,Performance,Datetime,Indexing,我想运行以下查询: 从weixin\u kol\u状态中选择url,其中创建时间为“2015-12-11 00:00:00”,创建时间为“2015-12-11 00:00:00”,创建时间为 如何使用覆盖索引 你知道a是什么吗?它是一个包含查询所需的所有列的索引。所以 以及 其中还包括第一个查询或 KEY `idx_user_created_url` (`userid`, `created_at`, `url`) 这对第一个查询不起作用,但可能会更好地优化第二个查询 您可能需要写出

我想运行以下查询:

从weixin\u kol\u状态中选择url,其中创建时间为“2015-12-11 00:00:00”,创建时间为“2015-12-11 00:00:00”,创建时间为
如何使用覆盖索引

你知道a是什么吗?它是一个包含查询所需的所有列的索引。所以

以及

其中还包括第一个查询或

      KEY `idx_user_created_url` (`userid`, `created_at`, `url`)
这对第一个查询不起作用,但可能会更好地优化第二个查询

您可能需要写出
url(512)
,而不仅仅是
url
VARCHAR
列索引不好。如果您得到一个关于索引值太宽的错误,您可能无法在此查询中使用覆盖索引

覆盖索引很有用,因为它可以回答从内存中的索引到磁盘上的表的所有内容。因为内存比磁盘快,所以它具有加速查询的效果。当然,如果索引被调出,您仍然需要从磁盘加载它。因此,如果您的内存有限,这可能没有帮助

请注意,一个查询在每个表中只使用一个索引,因此每列上的单独索引不会覆盖这两个查询。您需要一个复合索引来同时覆盖所有需要的列


作为旁注,我认为您的
=
几个问题

  • UNIQUE(url(255))
    将前255个字符限制为唯一;这可能不是我们想要的

  • 如果需要强制长字符串(
    url
    )的唯一性,请使用
    MD5(url)
    添加另一列,并使该列
    唯一。(或者类似的事情。)

  • 索引中每列有767字节的限制,因此如果您尝试创建
    索引(在url处创建)
    ,您将得到
    索引(在url处创建)(255))
    ,但该索引没有覆盖,因为并非所有
    url
    都在索引中

  • 这两个
    解释
    对于本次讨论都是无用的,因为它们没有使用您询问的
    选项。在第一个例子中,它说
    使用索引
    ,因为你说
    选择id
    ;实际查询是
    选择url
    。这对性能有很大的影响

  • 你有一张很大的桌子。我认为
    分区没有办法提高速度

  • 这是表示一天
    的更好方法,其中

         created_at >= '2015-12-11'
     AND created_at  < '2015-12-11' + INTERVAL 1 DAY
    
    这样做:

    PRIMARY KEY(created_at, id),
    INDEX(id)
    
    这将在
创建的
上“聚集”,从而显著减少I/O,特别是对于第一个
选择
。是的,
自动增量
可以只
索引
,而不是
唯一
主键


注意:进行更改将花费数小时和大量磁盘空间。

由于这已成为关于如何使用覆盖索引的一个具体问题,因此不再要求检查代码。辅助索引与数据一样在内存中进行分页。也就是说,索引不一定“从内存中的索引中回答所有问题”。一个“覆盖”索引就好了。但是
url
太大了,不能放在任何索引中。
select url from weixin_kol_status where created_at>'2015-12-11 00:00:00' and created_at<'2015-12-11 23:59:59';
      KEY `idx_created_url` (`created_at`, `url`)
select url from weixin_kol_status where userid in ('...') and created_at>'2015-12-11 00:00:00' and created_at<'2015-12-11 23:59:59';
      KEY `idx_created_user_url` (`created_at`, `userid`, `url`)
      KEY `idx_user_created_url` (`userid`, `created_at`, `url`)
     created_at >= '2015-12-11'
 AND created_at  < '2015-12-11' + INTERVAL 1 DAY
PRIMARY KEY (`id`),
KEY `idx_created_at` (`created_at`)
PRIMARY KEY(created_at, id),
INDEX(id)