首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组织“哪里”使它更快

组织“哪里”使它更快
EN

Stack Overflow用户
提问于 2015-04-10 17:16:53
回答 4查看 36关注 0票数 2

,重要的事情,

是否可以确定WHERE条件的最佳顺序以使其更快?例如,我有一个带有6个条件的查询。有些简单,有些带有子查询或函数。我的想法是对查询进行概要分析,以确定条件词是true的常见程度以及运行它的成本。

阅读示例

例如,我有:

代码语言:javascript
复制
WHERE
    table.ageMin >= :ageFilter AND       #1 age-more-than
    table.ageMax <= :ageFilter AND       #2 age-less-than
    YEAR(table.date) >= :dateFilter AND  #3 year
    (SELECT ...) = TRUE AND              #4 first-query
    (SELECT ...) = FALSE AND             #5 second-query
    USER_FUNCTION(table.tag, :tagFilter) #6 user-function

让我们说,在一个月内,我们有:

  1. 在95%的情况下是正确的;
  2. 在69%的情况下是正确的;
  3. 在15%的情况下是正确的;
  4. 在97%的情况下是正确的;
  5. 在50%的情况下是正确的;
  6. 在99%的情况下是正确的;

并考虑到(伪ms值):

  1. 是一个简单的条件和成本0.005ms的查询;
  2. 是一个简单的条件和成本0.005ms的查询;
  3. 使用MySQL年()并花费0.030ms进行查询;
  4. 使用子查询,查询成本为0.140 Use;
  5. 使用子查询,查询成本为0.260ms;
  6. 使用用户功能,查询成本为0.450ms;

所以,我可能会这样想:

  1. #3将在85%的时间内失效,查询成本仅为0.030ms;
  2. #2将在31%的时间内失败,查询成本仅为0.005ms;
  3. #1将在5%内失败,但查询成本仅为0.005ms;
  4. #5的成本比#4高出+0.120ms,但在50%的时间内就会失败;
  5. #4花费0.140 of,但失败率仅为3%;
  6. #6花费0.450ms,但失败率仅为1%;

所以我的订单会是:

代码语言:javascript
复制
WHERE
    YEAR(table.date) >= :dateFilter AND  #3 up, up
    table.ageMax <= :ageFilter AND       #2 maintained
    table.ageMin >= :ageFilter AND       #1 down down
    (SELECT ...) = FALSE AND             #5 up
    (SELECT ...) = TRUE AND              #4 down
    USER_FUNCTION(table.tag, :tagFilter) #6 maintained

因此,如果我在一个月内有1.000.000个查询,那么在第一个示例中,我将有:

  1. 5%的人在年老时会失败--超过5.000秒,休息950.000秒;
  2. 31%的人在年龄不到4.750秒,休息655.500秒时就会失败;
  3. 85%的人会在一年中失败,花费19.665秒,休息98.325秒;
  4. 3%将失败在第一个子查询,花费13.765秒,其余95.375;
  5. 50%会在第二次子查询失败,花费24.797秒,其余47.687秒;
  6. 1%的用户功能将失败,花费21.459秒,其余47.210秒;

因此,在100万个查询中,只有47.210是真的。它将花费89.436秒来处理所有的查询。

在我重新订好我的位置之后,它会是:

  1. 85%会在一年中失败,花费30.000秒,休息150.000秒;
  2. 31%的人在年龄不到750秒,休息103.500秒时就会失败;
  3. 5%的人在年龄上会失败--超过517秒,休息98.325秒;
  4. 50%会在第二次子查询失败,花费25.564秒,其余49.165秒;
  5. 3%将失败在第一个子查询,花费6.883秒,其余47.690;
  6. 1%的用户功能将失败,花费21.460秒,其余47.210秒;

因此,在100万次查询中,它将花费85.174秒,比原来的订单少4.262秒。在这个简单的比较中,差别是5%,但我有大约50个条件表(有些复杂,另一些没有)。我试图修复order,查询从0.500ms减少到0.075ms。

但是,这是一项艰苦的工作,一个一个地检查,然后决定哪一个更常见,哪些成本更低。那么,有什么工具可以让这件事成功吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-10 17:38:22

WHERE子句中条件的顺序并不重要。MySQL查询优化器对查询执行许多类型的变化,以使其尽可能快地运行。

由于子查询,您的查询速度很慢。优化器可以将某些类型的子查询转换成表连接,这一变化大大提高了运行速度。

我不能建议对您的子查询进行任何改进,因为您没有提供它们。

您可以很容易地改进条件YEAR(table.date) >= :dateFilter的评估。函数(YEAR())的使用阻止MySQL使用索引。如果将其更改为将table.date与一年中的第一天进行比较(例如,在dateFilter中使用2015-01-01而不是2015 ),那么MySQL可以使用索引并加快执行速度。

当然,如果您已经为该MySQL创建了索引,那么column.Be将使用一个索引,确保您在dateageMinageMax列上都有索引。

EXPLAIN放在查询前面,并对照EXPLAIN output format文档检查结果,找出查询速度慢的原因以及如何改进查询。

票数 2
EN

Stack Overflow用户

发布于 2015-04-10 17:20:32

不,mysql中的优化器并不关心where条件的顺序。它使用统计信息(直方图)来确定应用where语句的顺序(并使用正确的索引:使索引就位)。如果它真的偏离目标,您可以使用提示并强制使用某个索引,但是您的查询只针对这一种情况进行了优化,这对其他情况的性能非常不利。

票数 1
EN

Stack Overflow用户

发布于 2015-04-10 18:04:08

MySQL的查询计划器重新排序由AND连接在一起的AND子句,从而得出它所猜测的最佳执行计划。

您不能通过在查询中乱动子句的顺序来影响这一点。

一旦您的表大部分被填充,您可以使用ANALYZE TABLE来影响它。

您可能会通过创建一个或多个具有与查询中列匹配的列的复合索引来影响它。看看这个。http://use-the-index-luke.com/

如果您正在进行基准测试,请确保在查询开始时编写SELECT SQL_NO_CACHE而不是SELECT。否则,MySQL将满足来自缓存的重复查询,并且显示得非常快。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29567147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档