员工(ename,title,dname,address) 所有都是相同长度的字符串字段。
ename属性是候选键。 该关系包含10,000页。 有10个缓冲页面。
查询是: SELECT E.title,E.ename 来自员工E. WHERE E.title ='管理员'
假设只有10%的Employee元组符合选择条件。
假设ename上的聚簇B +树索引是(唯一的索引)可用。最佳计划的成本是多少?
我如何计算这笔费用?如果标题上有一个聚类B +树索引,我该如何计算?
另一个问题: 选择E.ename 来自员工E. WHERE E.title ='管理员' AND E.dname ='财务'
假设只有10%的员工元组符合条件E.title ='Administrator',只有10%符合E.dname ='Finance',只有5%满足这两个条件。
假设群集B +树索引是(唯一的索引)可用。最佳计划的成本是多少?
专家!请帮忙。任何意见/建议将不胜感激。我想了解整个过程。我做了很多研究,我想我知道如何计算每个操作的成本,让我感到困惑的是他们说这个关系包含10,000页而不是说每个页面中有多少元组?从我学到的东西,我相信我们必须有关于元组的关系的总大小,我是否正确?为什么呢?
感谢任何花时间阅读问题的人: - )
答案 0 :(得分:1)
如果没有合适的索引,查询将执行表扫描。由于读取行是执行时间的主要部分(在许多情况下);你提到的变化并不重要。
如果你有一个相关的索引,和那个索引足够有选择性(10%可能足够“有选择性”),那么查询将有两个步骤:
PRIMARY KEY
(假设您使用的是InnoDB)。使用该PK,在主BTree中查找包含PK和数据的行。如果所有必要的块都缓存在buffer_pool中(同样,假设InnoDB),成本的变化相当小。
如果并非所有块都在缓存中(因为mysqld刚刚启动,或者因为索引/数据太大而无法保持缓存),那么您将“计算磁盘命中率”。这是因为“成本”的主要部分是I / O.现在计算成本非常复杂,因为需要知道已经缓存了多少百分比,查询是否会“破坏”缓存,10%是均匀分散,还是聚集在一起,或者介于两者之间。
由于(对于InnoDB),PK与数据“聚集”,因此PK的查找与通过辅助键的查找不同。
10K行是“小”。 10个缓冲页面 - 你的意思是什么? “所有都是相同长度的字符串字段” - 使用CHAR
代替VARCHAR
是不现实的,不是一个好主意。无论如何,字符串长度对这个讨论几乎没有影响。
WHERE E.title=‘Administrator’ AND E.dname=‘Finance’
- 以 顺序为INDEX(title, dname)
提出要求。
“经验法则”:一个块(InnoDB)可以容纳100行(数据或索引)。 (当然,这可能会有很大差异。但有时候“计算磁盘命中率”很方便。)
在我的cookbook中,我发现更容易专注于设计“最佳”索引,而无需计算“成本”。
有关查询的进一步说明
“假设只有10%的员工元组符合条件E.title ='管理员',只有10%符合E.dname ='财务',只有5%满足这两个条件。”对于MySQL,这里有更多细节:
案例1:INDEX(title)
- 类似于第一个查询 - 索引范围扫描为10%,然后探测数据。
案例2:INDEX(dname)
- 同上。
情况3:两个索引 - 有一个 slim 机会使用“索引合并交叉”来做两个索引“范围扫描”,将两个集合在一起,然后到达行的数据。
案例4(最好):INDEX(title, dname)
(或相反的顺序):返回索引范围扫描,但仅限于5%的项目。
MySQL的首选引擎是InnoDB。我所讨论的是假设,而不是MyISAM。使用InnoDB,“数据”存储在B +树中,每个二级索引也是如此。在考虑如何执行查询时,请记住这种相似性。另请注意,辅助索引的“叶节点”包含PK,从而提供了查找记录其余部分的机制。