当前位置: 首页 > 面试题库 >

如何告诉MySQL优化程序在派生表上使用索引?

马德厚
2023-03-14
问题内容

假设您有这样的查询…

SELECT T.TaskID, T.TaskName, TAU.AssignedUsers
FROM `tasks` T
    LEFT OUTER JOIN (
        SELECT TaskID, GROUP_CONCAT(U.FirstName, ' ',
            U.LastName SEPARATOR ', ') AS AssignedUsers
        FROM `tasks_assigned_users` TAU
            INNER JOIN `users` U ON (TAU.UserID=U.UserID)
        GROUP BY TaskID
    ) TAU ON (T.TaskID=TAU.TaskID)

可以将多个人分配给给定任务。该查询的目的是显示每个任务一行,但将分配给该任务的人员显示在单个列中

现在…假设你有正确的指标设置上tasksuserstasks_assigned_users。连接tasks到派生表时,MySQL
Optimizer仍将不使用TaskID索引。WTF?!?!?

因此,我的问题是…如何使此查询使用task_assigned_users.TaskID上的索引?临时表是la脚的,所以如果这是唯一的解决方案,那么MySQL
Optimizer是愚蠢的。

使用的索引:

  • 任务
    • 主要-TaskID
  • 使用者
    • 主要-用户ID
  • task_assigned_users
    • 主要-(TaskID,UserID)
    • 附加索引UNIQUE-(UserID,TaskID)

编辑: 此外,此页面还说派生表在联接发生之前已执行/实例化。为什么不重新使用键来执行联接?

编辑2: MySQL
Optimizer不允许您在派生表上放置索引提示(大概是因为派生表上没有索引)

编辑3: 这是一个关于此的非常好的博客文章:http :
//venublog.com/2010/03/06/how-to-improve-subqueries-derived-tables-
performance/ 注意案例2是我的解决方案正在寻找,但MySQL目前不支持此功能。:(

编辑4: 刚刚发现这个:“在MySQL
5.6.3,优化更有效地处理子查询在FROM子句(即派生表):......在查询执行,优化程序可以添加一个索引来派生表加快从中进行行检索的速度。”
似乎很有希望…


问题答案:

在MySQL Server 5.6中,有一个解决方案-预览版(在撰写本文时)。

http://dev.mysql.com/doc/refman/5.6/en/from-clause-subquery-
optimization.html

虽然,我不确定在“将索引添加到派生表中”时MySQL Optimizer是否会重用已经存在的索引。

考虑以下查询:

SELECT * FROM t1 JOIN(SELECT * FROM t2)AS named_t2 ON t1.f1 = derived_t2.f1;

该文档说:“如果这样做可以允许对最低成本的执行计划使用ref访问,那么优化程序将在f1的f1列上构造一个索引。”

好的,那很好,但是优化程序会重用t2的索引吗?换句话说,如果存在针对t2.f1的索引该怎么办?该索引会被重用,还是优化程序为派生表重新创建该索引?谁知道?

编辑: 直到MySQL 5.6,最好的解决方案是创建一个临时表,在该表上创建一个索引,然后在临时表上运行SELECT查询。



 类似资料:
  • 本文向大家介绍MySQL如何优化索引,包括了MySQL如何优化索引的使用技巧和注意事项,需要的朋友参考一下 1.  MySQL如何使用索引 索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以找到相关的行。表越大,花费越多。如果表中有相关列的索引,MySQL可以快速确定要在数据文件中间查找的位置,而不必查看所有数据。这比顺序读取每一行要快得多。 大多数MyS

  • 大多数C程序员都知道空基类优化是一种技术/习惯用法。空的子类会发生什么?例如 与EBO类似,应该有一个EDO声明,由于派生类不提供任何其他成员,也不向其参数化类型引入任何虚拟成员,因此它不需要更多内存。考虑到可能出现类似情况的各种情况(多重继承、单一继承……): 这样的优化标准/可能吗? 如果是,这种优化的机制是什么,它们与EBO相似吗? 注意:使用从参数化类型派生的类模板是相当典型的。主题是在这

  • 问题内容: 我想用Cython包装一个包含C ++和OpenMP代码的测试项目,并通过文件与distutils一起构建它。我文件的内容如下所示: 该标志与gcc一起用于针对OpenMP进行编译和链接。但是,如果我只是调用 由于编译器是clang,因此无法识别此标志: 我尝试指定gcc失败: 如何告诉distutils使用gcc? 问题答案: 尝试使用os.environ从setup.py内部设置“

  • 我想用Cython包装一个包含C和OpenMP代码的测试项目,并通过一个文件用distutils构建它。我的文件内容是这样的: 标志与gcc一起用于编译和链接OpenMP。然而,如果我只是调用 无法识别此标志,因为编译器为clang: 我尝试指定gcc失败: 如何告诉distutils使用gcc?

  • 问题内容: 我有一个查询,看起来像: 尽管我对资源有索引,但它不使用它。如何优化将其用于按位运算。 问题答案: 我不认为MySQL可以使索引用于按位操作。 MySQLPerformance论坛中对此进行了一些讨论:http : //forums.mysql.com/read.php?24,35318(“按位比较可以进行索引扫描吗?”),MySQL员工根据每对(事物,设置位)对具有一行并进行一堆联接

  • 问题内容: 我有一个小而狭窄的InnoDB表,大约有900万条记录。在桌子上或桌子上做的速度非常慢(超过6秒): 虽然该语句不是运行得太频繁,但对其进行优化将是不错的选择。根据http://www.cloudspace.com/blog/2009/08/06/fast- mysql-innodb-count-really- fast/, 这可以通过强制InnoDB使用索引来实现: 解释计划似乎很好