php索引-MySQL 索引使用策略与优化

MySQL优化主要分为方案优化和查询优化。

本章讨论的高性能索引策略主要属于结构优化范畴。本章的内容完全基于上述理论基础,其实一旦理解了索引背后的机制,高性能策略的选择纯粹是推理,但这个策略背后的逻辑是可以理解的。

1. 示例数据库

为了讨论索引策略,需要一个包含少量数据的数据库作为示例。本文使用官方 MySQL 文档中提供的示例数据库之一:员工。该数据库具有中等关系复杂性和大量数据。右图是该数据库的E-R图(参考自官方MySQL指南):

您可以.sql可以放入员工的文件

二、最左边的前缀原则及相关优化

有效使用索引的第一个条件是知道哪些类型的查询将使用索引,这与 B+Tree 中的“最左边的前缀原则”有关,最左边的前缀原则由下面的示例说明。

让我们从联合索引的概念开始。综上所述,我们都假设索引只引用单个列,实际上,MySQL中的索引可以按一定的顺序引用多个列,这些索引称为联合索引。

通常,联合指数是

一个有序元组,其中每个元素都是数据表的一列,其实关系代数是严格定义索引需要的,关系代数我不想在这里过多讨论,因为它会变得很枯燥,所以这里就不严格定义了。此外,可以将单列索引视为具有多个元素为 1 的联合索引的特例。

以 employees.title 表为例,我们来检查一下上面有哪些索引:

php引入php_两个索引数组求差php_php索引

3. 解释

在日常工作中,我们有时会打开慢查询来记录一些需要很长时间才能执行的SQL句子,发现那些SQL句子并不意味着结束了,有时候我们经常使用独占命令来查看一个SQL句子的执行计划,检查SQL句子是否使用了索引, 是否进行全表扫描,可通过独占命令查看。

因此,我们深入研究了 MySQL 的基于花费的优化器,我们还可以获得有关优化器可能考虑的访问策略的大量详细信息,以及优化器在运行 SQL 句子时预期采用哪种策略。

“说明”下有 10 列信息,分别是 id、select_type、表、类型、possible_keys、键、key_len、引用、行和额外

简要说明:

4.具体内容情况一:全栏匹配

解释选择*FROMemployees.titlesWHEREemp_no='10001'ANDtitle='高级工程师'ANDfrom_date='1986-06-26';

值得注意的是,在基于索引中的所有列执行完全匹配时,可以使用索引(此处完全匹配表示“=”或“IN”匹配)。这里需要注意的是,索引在理论上对顺序很敏感,并且由于MySQL的查询优化器手动调整where谓词的条件顺序以使用适当的索引,例如,如果我们反转where中的条件顺序,它具有相同的效果。

情况 2:最左侧的前缀匹配

解释选择*FROMemployees.titlesWHEREemp_no='10001';

当查询条件与索引一侧的一行中的一列或多列完全匹配时,如 或 ,则可以使用,并且只能使用条件最左侧的前缀。里面的查询使用分析结果中的主索引,key_len为4,表示只使用索引的第一列前缀。

情况 3:查询条件使用索引中列的完全匹配,并且未提供中间条件之一

解释选择*FROMemployees.titlesWHEREemp_no='10001'ANDfrom_date='1986-0626';![MySQL 索引使用策略与优化](!

此时,索引使用情况为

和情况二一样,因为没有提供标题,所以查询只使用索引的第一列,旁边的from_date好像在索引中,又因为标题不存在,不能和左前缀连接,所以需要扫描过滤结果from_date(这里因为emp_no是唯一的, 没有扫描)。

如果希望from_date也使用索引而不是 where 筛选,则可以降低上一个查询将使用的二级索引。此外,可以使用称为“隔离柱”的优化来填充emp_no和from_date之间的“坑”。

首先,让我们看一下标题,它有几个不同的值:

只有7种类型。如果成为“pits”的列值相对较少,请考虑使用“IN”来补偿此“pit”以生成最左侧的前缀:

这次key_len是56,说明索引被完全使用,从类型和行可以看出IN实际执行了范围查询,这里检测到7个键。

“填坑”后性能有所改善。如果emp_no过滤后还剩下大量数据,前者的性能优势会更加显著。其实,如果标题的价值很多,就不宜填坑,辅助指标必须提高。

情况四:查询条件未指定索引的第一列

因为它不是最左边的前缀,所以索引对于索引等查询没有用。

案例 5:匹配列的前缀字符串

在这种情况下可以使用索引,如果键值不只出现在末尾,则很难使用索引。(原描述不正确,如果开头没有出现键 %,可以使用索引,但视情况而定,只能使用其中一个前缀)。

案例6:范围查询

两个索引数组求差php_php索引_php引入php

范围列

可以使用索引(必须是最左边的前缀),范围列旁边的列很难使用索引。同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列,则索引未完全使用。

您可以看到该索引对第二个范围索引无能为力。MySQL的一个有趣的方面是,仅使用解释很难区分范围索引和多值匹配,因为所有三个都显示为类型范围。此外,使用“between”并不意味着它是一个范围查询,例如以下查询:

似乎使用了两个范围查询,但作用于emp_no的“BETWEEN”实际上等同于“IN”,也就是说emp_no它实际上是多个值的精确匹配。可以看到此查询使用索引的所有三列。因此,在 MySQL 中,需要仔细区分多值匹配和范围匹配,否则会对 MySQL 的行为造成麻烦。

案例 7:索引选择性和前缀索引

既然索引可以驱动查询速率,那么只要查询句子需要索引php索引,是否有必要构建索引?答案是否定的。由于索引实际上驱动查询速率,索引也是有代价的:索引文件本身占用存储空间,索引增加了插入、删除和更改记录的负担,MySQL 还会消耗资源在运行时维护索引,因此索引越多越好。通常,不建议在这两种情况下使用索引。

第一种情况是表记录相对较少,比如一个表有一两千条甚至只有几百条记录,就不需要建索引php索引,让查询做全表扫描。至于记录多少是太多,这个人有个人想法,我个人的经验是用2000作为分界线,记录数不超过2000可以考虑不索引,超过2000可以考虑索引为宜。

不建议编制索引的另一种情况是索引的选择性较低。所谓索引选择性,是指非重复索引值(也称为基数)与表记录数(#T)的比率。

Index Selectivity = Cardinality / #T

实际上,选择性的值范围是

(0,1],选择性越高,指数值越大,这是由B+树的性质决定的。比如上面用的 employees.titles 表,如果经常单独查询 title 数组,是否需要构建索引,我们来看看它的选择性:

标题的选择性低于 0.0001(确切地说是 0.00001579),因此实际上没有必要单独索引它。有一种与索引选择性相关的索引优化策略称为前缀索引,即用列的前缀作为索引键

替换整列,当前缀宽度合适时,不仅可以促进前缀索引的选择性接近全列索引,还可以由于索引键的缩短而降低索引文件的大小和维护成本。下面以 employees.employee 表为例,介绍前缀索引的选择和使用。

从示例数据库图中,我们可以看到 employee 表只有一个索引,所以如果要按姓名搜索一个人,我们只能扫描整个表,如果我们经常按姓名搜索员工,即使效率低,那么我们可以考虑构建一个索引。有两个选项,构建或查看两个索引的选择性:

其实选择性太低了,选择性

很好,但是first_name和last_name加上宽度是30,有没有办法将宽度和选择性结合起来? 例如,>>考虑索引first_name和last_name的前几个字符,瞧,选择性:![MySQL 索引使用策略与优化](!

此时选择性已经很理想了,这个索引的宽度只有18,缩短了近一半,我们构建了这个前缀索引:“ALTERTABLEemployees.employeesADDINDEX'first_name_last_name4'(first_name,last_name(4));'''此时再次按名称执行子查询,将结果与索引构建进行比较:性能提升明显,查询率提升了 120 多倍。

>>前缀索引同时具有索引大小和查询速率,它们的缺点是不能用于 ORDERBY 和 GROUPBY 操作,也不能用于 Coveringindex(即当索引本身包含查询所需的所有数据时,不再访问数据文件本身)。

MySQL 笔试

本作品采用“CC合同”,转载须注明作者及本文链接

PHP基本分页原理+分页码+分页类系统。分页显示是浏览和显示大量数据的一种非常常见的方式php 分类php 分类,也是 Web 编程中最常见的风暴之一。对于 Web 编程的老鸟来说,编译这段代码就像呼吸一样自然,而对于初学者来说,他们往往对这个问题有一无所知,所以连兄弟 PHP 培训的小编特意写了这篇文章来详细讲解这个问题。

分页原理

php 分类_分类汇总怎么操作excel_分类信息网php源码

所谓分页显示,就是人为地将数据库中的结果集划分成段落进行显示,这里需要两个初始参数:

每页有多少条记录 ($PageSize)?

当前是哪个页面($CurrentPageID)?

现在只需给我另一个结果集,我就可以显示一个特定的结果。

至于其他参数,比如:上一页($PReviousPageID)、下一页($NextPageID)、总页数($numPages)等,你可以根据前面的东西得到。

以 MySQL 数据库为例,如果要从表中提取某段内容,可以使用 SQL 语句:select*fromtablelimitoffset、rows。看看下面的一组SQL句子,并尝试发现规律性。

前 10 条记录: 选择*从表限制0,10

记录 11 到 20: 从表限制中选择*10,10

记录 21 到 30: 从表限制中选择*20,10

......

这组 SQL 句子似乎是 $PageSize=10 时获取表中每一页数据的 SQL 句子,我们可以总结这样一个模板:select*fromtablelimit($CurrentPageID-1)*$PageSize,$PageSize

拿这个模板,把它和上面的一组SQL句子进行比较,看看是否是这种情况。在解决了如何获取数据这个最重要的问题之后,剩下的就是传递参数,构造适当的SQL句子,然后使用PHP从数据库中检索数据并显示出来。

分页代码说明:

代码中完全解释的五个步骤可以复制到您自己的记事本中并直接使用