Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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 - Fatal编程技术网

是否有任何MySQL函数可以获取开始日期或结束日期介于给定开始日期和结束日期之间的所有行第二部分

是否有任何MySQL函数可以获取开始日期或结束日期介于给定开始日期和结束日期之间的所有行第二部分,mysql,Mysql,在后续报道中:我遇到了这样一个问题:从数千条记录中,无法真正使用正确的索引 不久前,我自己提出了提供的答案,现在已经实施了一段时间。现在,数据库中有数千个事件,分别在startdatetime和enddatetime列上建立索引,但由于查询本身的原因,mysql interperter无法真正使用它们: SELECT * FROM table WHERE start_date <= end_of_range AND stop_date >

在后续报道中:我遇到了这样一个问题:从数千条记录中,无法真正使用正确的索引

不久前,我自己提出了提供的答案,现在已经实施了一段时间。现在,数据库中有数千个事件,分别在startdatetime和enddatetime列上建立索引,但由于查询本身的原因,mysql interperter无法真正使用它们:

SELECT * FROM table WHERE start_date <= end_of_range
                      AND stop_date  >= start_of_range

换句话说:整张桌子?现在需要澄清的是:根据定义,查询并不慢,但它也不使用任何索引

您的逻辑是反向的,使服务器扫描过多的记录以进行匹配

请尝试以下方法:

SELECT * FROM table WHERE start_date >= start_of_range 
                      AND stop_date <= end_of_range

这将利用索引,因为它可以快速定位开始日期,然后只在索引中向前移动。它还可以在停止日期快速定位您的索引,然后只需向后扫描行。

您所描述的可能不是问题

在您的测试查询中,mysql正在考虑使用2个索引,这就是您所能要求的:它不使用任何索引,因为统计数据告诉它,与索引相比,表扫描将更加高效

我假设在您的示例中,您的测试查询的选择性不足以触发您的测试用例处理1个月数据范围的索引的使用-满足条件的数据百分比是多少?根据每个索引

您唯一可以改进的是创建一个复合索引,因为我认为在您的示例中,mysql将无法帮助您。所以,要意识到这是一种不同的情况

2个索引,一个位于startDateTime,另一个位于endDateTime 相比

1 startDateTime和endDateTime上的综合指数 对于在某个范围内开始并在endDateTime上应用其他条件的事件,此索引应该最有用

您还可以考虑使用另一个索引:EntDeTimeTimeTimeDeaTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTimeTime


您还可以继续阅读,看看强制索引或修改某些服务器端变量会如何影响性能。

让我们尝试将问题一分为二,然后混合结果

SELECT * FROM table t INNER JOIN (
    SELECT id FROM table WHERE start_date <= end_of_range
    ) AS sd ON t.id = sd.id INNER JOIN (
    SELECT id FROM table WHERE end_date >= start_of_range
    ) AS ed ON t.id = ed.id
我假设您在名为id的表上有一个主键,这可能会使用start_date和end_date列上的索引,但会使用临时表来合并结果

SELECT * FROM table t INNER JOIN (
    SELECT id FROM table WHERE start_date <= end_of_range
    ) AS sd ON t.id = sd.id INNER JOIN (
    SELECT id FROM table WHERE end_date >= start_of_range
    ) AS ed ON t.id = ed.id

如果事件表持续增长,您可能希望使用临时表而不是派生表。首先只使用事件的id填充临时表,然后在临时表的id列上创建索引,最后进行联接。

您是否尝试在一个索引中的开始日期和停止日期两列上创建索引?因为我没有选择每列的范围,这有关系吗?“开始日期”和“停止日期”是两个不同的列。顺便说一句,我们尝试过,但没有用。您可以发布解释计划吗?用解释编辑了问题,但您的查询返回了错误的结果?最初的问题仍然存在:在范围之前开始但在范围内结束的事件,在范围内开始但在范围外结束的事件,在该范围内开始和结束的事件,以及在该范围之前和之后开始的最后但并非最不重要的事件…您提出的是一个糟糕的策略-临时表是最后一个选项,可扩展性和复杂性会转化为维护问题,如果您重用某些结果集,并且在特定场景中可能丧失一致性,那么这可能是一种收益-缓存/会话表也可以,但是上面的建议并不能作为一种通用方法。@Unreason,那么您将如何优化有问题的查询?请阅读我的答案。首先要尝试的是复合索引。第二,他可能正在处理一个无问题的问题——明确地说,查询的性能并不差,只是他希望看到DB使用索引——当对现有和可用索引的选择性达到某个阈值时,它会这样做。在这个阶段使用临时表几乎可以肯定是过早的优化——这是万恶之源——D。Knuth加上它甚至可能不是优化,但可能会产生相反的效果——整个表跨越6年以上,即使我将范围降低到24小时,也无济于事。。。还是完整扫描。。。顺便说一句,添加索引/复合索引没有任何帮助…正如我在上面所问的那样-实际满足标准的数据百分比是多少?另外,尝试强制索引,看看会发生什么。如果您的查询执行得更差,那么mysql是一件好事。选择一个24小时的时间段可以得到79727行中的49行,但仍然使用完整的表扫描!对我来说,这个查询的问题是,它对每个索引使用单个条件,因此无法真正快速地缩减结果…这就是为什么复合查询 索引应该起作用。您是否也尝试创建endDateTime和startDateTime?