如何优化数据库中的查询 - 基础知识

wal*_*mon 6 mysql sql database optimization query-optimization

似乎关于这个主题的所有问题都是非常具体的,虽然我重视具体的例子,但我对SQL优化的基础知识很感兴趣.我非常适合在SQL中工作,并且具有硬件/低级软件的背景知识.

我想要的是有形软件的工具,以及查看我定期查看的mysql数据库的方法,并了解join语句和where语句之间的区别.

我想知道为什么索引有助于确切原因.我想知道具体发生了什么,我想知道如何才能真正看到正在发生的事情.我不需要一个会破坏我SQL的每一步的工具,我只是想能够四处寻找,如果有人不能告诉我要索引的列,我将能够得到一张纸和在一段时间内能够拿出答案.

数据库很复杂,但它们并不复杂,并且必须有一些很好的材料来学习基础知识,这样你才能知道如何找到你遇到的优化问题的答案,即使可以找到一个确切的答案.论坛.

请推荐一些简洁,直观,并且不怕低级螺母和螺栓的阅读.我更喜欢在线免费资源,但是如果一本书的推荐拆除钉头,我会考虑接受它.

Ama*_*dan 7

假设您正在寻找另一个城市的朋友.一种方法是挨家挨户地询问这是否是您正在寻找的房子.另一种方法是查看地图.

索引是表的映射.它可以准确地告诉数据库引擎您正在寻找的东西.因此,您可以索引您认为必须搜索的每个列,并省略您刚刚从中读取数据的列,并且从不搜索.

良好的技术阅读有关指标关于ORDER BY优化.如果你想看看究竟发生了什么,你需要EXPLAIN声明.


Jay*_*Jay 6

您需要查看每个条件和每个连接的条件.两者的工作方式相同.

假设我们写

select name
from customer
where customerid=37;
Run Code Online (Sandbox Code Playgroud)

不知何故,DBMS必须找到customerid = 37的记录或记录.如果没有索引,唯一的方法是读取表中比较customerid到37的每条记录.即使找到一条,也无法知道只有一条,所以它必须继续寻找其他.

如果在customerid上创建索引,则DBMS可以非常快速地搜索索引.它不是顺序搜索,而是取决于数据库,二进制搜索或其他一些有效的方法.究竟怎么没关系,接受它比顺序要快得多.然后索引将其直接转到相应的记录或记录.此外,如果您指定索引是"唯一",则数据库知道只能有一个索引,因此它不会浪费时间寻找秒.(并且DBMS会阻止您添加秒.)

现在考虑这个查询:

select name
from customer
where city='Albany' and state='NY';
Run Code Online (Sandbox Code Playgroud)

现在我们有两个条件.如果您只在其中一个字段上有索引,则DBMS将使用该索引查找记录的子集,然后依次搜索这些记录.例如,如果您有状态索引,DBMS将快速找到NY的第一条记录,然后按顺序搜索查找city ='Albany',并在它到达NY的最后一条记录时停止查看.

如果您的索引包含两个字段,即"在客户(州,城市)上创建索引",则DBMS可以立即缩放到正确的记录.

如果您有两个单独的索引,每个字段一个,则DBMS将具有适用于决定使用哪个索引的各种规则.同样,具体如何完成取决于您使用的特定DBMS,但基本上它会尝试统计记录总数,不同值的数量和值的分布.然后它将按顺序搜索那些满足其他条件的记录.在这种情况下,DBMS可能会观察到有更多的城市而不是州,因此通过使用城市索引,它可以快速缩放到"奥尔巴尼"记录.然后它将依次搜索这些,检查每个对'NY'的状态.如果您有加州奥尔巴尼的记录,则会跳过这些记录.

每次加入都需要进行某种查找.

说我们写

select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';
Run Code Online (Sandbox Code Playgroud)

现在,DBMS必须首先决定要读取哪个表,从那里选择适当的记录,然后在另一个表中找到匹配的记录.

如果您在transaction.transactiondate和customer.customerid上有索引,那么最好的计划可能是查找具有此日期的所有交易,然后为每个交易找到具有匹配的customerid的客户,然后验证客户是否有正确的类型.

如果您没有customer.customerid上的索引,那么DBMS可以快速找到该事务,但是对于每个事务,它必须按顺序搜索customer表以查找匹配的customerid.(这可能会很慢.)

相反,假设您拥有的唯一索引位于transaction.customerid和customer.type上.然后DBMS可能会使用完全不同的计划.它可能会扫描客户表中所有具有正确类型的客户,然后为每个客户查找该客户的所有交易,并按顺序搜索他们的正确日期.

优化的最重要的关键是找出哪些索引真正有用并创建这些索引.额外的,未使用的索引是数据库的负担,因为它需要工作来维护它们,如果它们从未被使用过,则这是浪费精力.

您可以使用EXPLAIN命令告知DBMS将对任何给定查询使用哪些索引.我一直用这个来确定我的查询是否被很好地优化,或者我是否应该创建其他索引.(有关其输出的说明,请阅读此命令的文档.)

警告:请记住,我说DBMS会记录每个表中的记录数和不同值的数量等.如果数据发生变化,EXPLAIN今天可能会给你一个完全不同于昨天的计划.例如,如果您有一个连接两个表的查询,并且其中一个表非常小而另一个表很大,则它将偏向于首先读取小表,然后在大表中查找匹配的记录.向表中添加记录可以更改哪个更大,从而引导DBMS更改其计划.因此,您应该尝试使用实际数据对数据库执行EXPLAINS.针对每个表中包含5条记录的测试数据库运行的价值远远低于对实时数据库运行的价值.

嗯,还有更多可以说,但我不想在这里写一本书.