【问题标题】:mysql: which queries can untilize which indexes?mysql:哪些查询可以取消哪些索引?
【发布时间】:2009-12-29 22:21:09
【问题描述】:

我使用的是 Mysql 5.0,对索引有点陌生。索引可以帮助以下哪些查询以及我应该创建哪个索引?

(不要假设任何一个表都具有唯一值。这不是家庭作业,它只是我编写的一些示例,以尝试了解索引。)

Query1:
Select a.*, b.*
From a
Left Join b on b.type=a.type;

Query2:
Select a.*, b.*
From a,b
Where a.type=b.type;

Query3:
Select a.*
From a
Where a.type in (Select b.type from b where b.brand=5);

以下是我对这些不同类型查询将使用哪些索引的猜测:

Query1:
Create Index Query1 Using Hash on b (type);

Query2:
Create Index Query2a Using Hash on a (type);
Create Index Query2b Using Hash on b (type);

Query3:
Create Index Query2a Using Hash on b (brand,type);

Query1 或 Query3 都不会使用表 a 上的任何索引,我是否正确?

我相信这些都应该是哈希,因为只有 = 或 !=,对吧?

谢谢

【问题讨论】:

    标签: sql mysql optimization indexing


    【解决方案1】:

    在 mysql 中使用 explain 命令将提供很多关于 mysql 正在做什么以及如何优化查询的重要信息。

    在 q1 和 q2 中:(a.type,所有其他 a cols)上的索引和(b.type,所有其他 b cols)上的索引 在第三季度:(a.b_type,所有其他 a cols)上的索引和 b(品牌,类型)上的一个索引

    理想情况下,您希望所有选择的列都直接存储在索引中,这样 mysql 就不必从索引跳回表数据来获取选择的列。但是,这并不总是易于管理(即:有时您需要选择 * 并且索引所有列的成本太高),在这种情况下,只索引搜索列就可以了。

    所以你说的一切都很好。

    【讨论】:

    • 哇...是的,mysql 文档没有提到任何关于索引非连接列的内容。感谢您的提示!
    • 更好的方法是尽可能使用聚集索引,当然这并不总是可行的。
    • 是的,集群很棒。在 mysql 中,至少它只能在唯一的列上。 ms sql server 肯定对它有更好的支持。
    • 你的意思是聚集索引或者覆盖索引很好?聚集索引位于主键上,是行数据的存储方式。覆盖索引是包含查询中使用的所有列的任何索引。您绝对可以将非唯一列添加到索引以使其成为覆盖索引 - 只需注意索引大小。
    【解决方案2】:

    查询 3 无效,但我认为您的意思是

    where a.type in ....

    查询 1 与查询 2 相同,只是语法更好,两者可能具有相同的查询计划,并且都将使用两个索引。

    查询 3 将使用 b.brand 上的索引,但不使用它的类型部分。如果有的话,它也会使用 a.type 上的索引。

    你说得对,它们应该是哈希索引。

    【讨论】:

    • 对不起?查询 1 是一个外连接,无论如何它都会输出 'a' 中的所有值(而查询 2 不会)
    【解决方案3】:

    如果 brand=5 的 b 的数量接近于零,则查询 3 可以使用 a.type 上的索引

    Query2 将使用索引,如果它们是 B 树(因此是排序的)。使用带有索引连接的哈希索引可能会减慢您的查询速度(因为您必须以非顺序方式读取 Size(a) 值)

    【讨论】:

      【解决方案4】:

      查询优化和索引是一个庞大的话题,因此您肯定想了解 MySQL 和您正在使用的特定存储引擎。 InnoDB 和 NDB 支持“使用哈希”;我不认为 MyISAM 支持它。

      即使连接条件相等,您拥有的连接也会执行全表或索引扫描;每一行都必须被读取,因为没有 where 子句。

      使用标准的 b-tree 索引可能会更好,但测量它并使用“解释”调查查询计划。 MySQL InnoDB 存储按主键组织的行数据,因此您的表上还应该有一个主键,而不仅仅是一个索引。最好在连接中使用主键,否则 MySQL 会从索引中检索主键,然后再进行一次提取以获取该行。该规则的一个很好的例外是,如果您的二级索引包含查询中需要的所有列。这称为覆盖索引,MySQL 根本不需要查找该行。

      【讨论】:

      • 刚刚在dev.mysql.com/doc/refman/5.0/en/create-index.html 查找索引类型。 MyISAM 不支持哈希索引。我对 InnoDB 的看法是错误的——它也不支持哈希索引。它有一个基于 b-tree 索引构建的自适应散列系统。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 2016-08-27
      • 2012-07-28
      • 1970-01-01
      相关资源
      最近更新 更多