Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为具有多个列的MYSQL表编制索引_Mysql_Indexing - Fatal编程技术网

为具有多个列的MYSQL表编制索引

为具有多个列的MYSQL表编制索引,mysql,indexing,Mysql,Indexing,我有一个包含以下列的表: 开始时间:周日、周一、周二、周二、周四、周五、周六 起始日期为日期类型,其他为tinyint 我通过以下方式进行查询: SELECT * FROM posts WHERE start_at >= '2017-02-01' AND mon = 1 这是在第二天之后,我动态地设置了适当的星期几 索引此表的最佳方法是什么?我是否需要为一周中的每一天制作一个综合指数,例如: CREATE INDEX mon_index ON posts(start_at,mon); C

我有一个包含以下列的表:
开始时间:周日、周一、周二、周二、周四、周五、周六

起始日期为日期类型,其他为tinyint

我通过以下方式进行查询:

SELECT * FROM posts WHERE start_at >= '2017-02-01' AND mon = 1
这是在第二天之后,我动态地设置了适当的星期几

索引此表的最佳方法是什么?我是否需要为一周中的每一天制作一个综合指数,例如:

CREATE INDEX mon_index ON posts(start_at,mon);
CREATE INDEX sun_index ON posts(start_at,sun);
如果我为一周中的每一天创建7个索引,我认为插入和更新会非常慢


更新:我确实需要一周中每一天的专栏,因为用户设置发布帖子的日期。同时可能有几天。

您的模式设计得很奇怪。您当前的设置可能有助于轻松报告,但您是正确的,按照您的建议编制索引将产生糟糕的
insert
update
性能

我的建议是重构这个表。我建议您更改
posts
表中的列(开始时间,天),而不是当前的设置。在这种设计中,一天可以从太阳到周六,您只需要一个索引
(开始时间,天)

如果出于阅读/报告的原因确实需要当前格式(我不会责怪您),您可以始终设置一个以这种方式旋转数据的视图


综上所述,并不是每个符合条件的字段都需要在索引中。我的估计是,表中的绝大多数行只需按日期即可过滤。剩下的少数可能不需要编制索引以获得良好的读取性能



以另一种方式,为什么还要储存这一天?这可以根据日期来计算。

正如另一个人所说,可能仅仅在开始时编制索引就足够了

如果要调查包含发布后日期的索引(特别是如果您的表有很多字段,并且只想列出从发布日期开始的字段),可以创建如下表:

CREATE TABLE XX (start_at ..., which_day tinyint UNSIGNED);
还有像这样的索引

CREATE INDEX XX_IX01 (start_at, which_day);
使用某种编码,可以选择哪一天:

0=没有一天 2^0=太阳 2^1=周一 2^2=.. ... 2^6=sat

因此,例如,如果mon和sat为1,则该值应为2^1+2^6=2+64=66

如果可能,请避免选择*并填写所需字段

使用EXPLAIN检查db引擎如何使用索引/表

此链接可能有用:

样本数据:

CREATE table et1 (start_at DATE, which_day tinyint UNSIGNED);
CREATE INDEX ET1_IX1 ON et1(start_at, which_day);

INSERT INTO et1 VALUES ('20170701', 132);
INSERT INTO et1 VALUES ('20170702', 3);
INSERT INTO et1 VALUES ('20170704', 5);
INSERT INTO et1 VALUES ('20170630', 2);


SELECT start_at, which_day, which_day & 128 AS X FROM et1;
SELECT start_at, which_day, which_day & 128 AS X FROM et1 WHERE start_at>'20170630' AND which_day & 128 =128;
EXPLAIN SELECT * FROM et1 WHERE start_at>'20170630' AND which_day & 128 =128;

DROP table et1;

您的数据库模式过于复杂,不需要添加所有这些列,也不需要创建大量索引

您可以将post表简化为:

id | title | (...) | start_at
然后可以替换此查询:

SELECT * FROM posts WHERE start_at >= '2017-02-01' AND mon = 1
而是使用以下功能:

SELECT * FROM posts WHERE start_at >= '2017-02-01' AND DAYOFWEEK(start_at) = 2
(1=周日,2=周一,…,7=周六)


然后,您可以在列的
start\u上保留一个索引。

为什么需要此表?在我看来,只有一个日期栏更有意义。关于索引,这取决于您计划如何使用该表。在同一条记录上,sun、mon等中的多个可以是1?问这个可能更好?这张桌子的用途是什么?可能有一个比您的设计更好的解决方案,我不确定给出的答案是否是最好的解决方案,因为我们没有足够的信息从您那里了解您试图在这里做什么。我确实需要一周中的每一天的专栏,因为用户设置了发布帖子的日期。“可能有几天是同时发生的。@Statscoder实际上,在这种情况下,您应该添加更多的行,而不是更多的列。