列索引的有效性是不是与列数据的熵有关

Posted

技术标签:

【中文标题】列索引的有效性是不是与列数据的熵有关【英文标题】:Is the effectiveness of a column index related to the entropy of the column data列索引的有效性是否与列数据的熵有关 【发布时间】:2017-03-13 07:08:24 【问题描述】:

作为关系数据库(Postgres、mysql)的消费者和偶尔的消费者,我经常不得不在各种查询的上下文中考虑查询速度。但是,您通常不知道数据库将如何使用或瓶颈可能在哪里,直到它投入生产。

这让我想知道,我可以使用关于列的预测熵的经验法则作为猜测该列的索引速度增加的启发式方法吗?

通过 Google 快速搜索计算机科学专业毕业生为计算机科学专业毕业生撰写的论文。对于自学成才的程序员,你能用“外行”的术语来概括吗?


熵?:我将熵定义为行数除以一个值平均重复的次数(平均值)。如果这对于有 CS 词汇的人来说是一个糟糕的词选择,请建议一个更好的词。

【问题讨论】:

要搜索的词是基数 谢谢!我不知道基数可以在那种情况下使用,我以为它只用于描述关系。 谷歌并阅读网站:dev.mysql.com 页面重新索引/索引/索引/等,优化/优化器/等和高效/高效/等。 我找到了来自 IBM 的 this article,它解释了为什么低基数列也会降低查询性能。 您还应该查看术语“选择性以及它与索引查询条件的关系。 【参考方案1】:

这个问题实在是太宽泛了,无法彻底回答,但我会尝试总结一下 PostgreSQL 的情况(我对其他 RDBMS 了解不多,但我写的一些内容适用于其中的大多数)。

而不是你上面建议的 entropy,PostgreSQL 术语是特定条件的 selectivity,它是一个介于 0 和 1 之间的数字,定义为满足条件的行数除以表中的总行数。具有低选择性值的条件(有点反直觉)称为高度选择性

确定索引是否有用的唯一可靠方法是比较使用和不使用索引的执行时间。

当 PostgreSQL 决定对表的条件使用索引是否有效时,它会将整个表的顺序扫描的估计成本与使用索引扫描的成本进行比较适用指标。

由于顺序读取和随机 I/O(用于访问索引)的速度通常不同,因此有几个参数会影响成本估算并因此影响决策:

seq_page_cost:顺序获取磁盘页面的成本 random_page_cost: 非顺序获取磁盘页面的成本 cpu_tuple_cost: 处理一个表行的成本 cpu_index_tuple_cost:在索引扫描期间处理索引条目的成本

这些成本以虚数单位衡量,习惯上将seq_page_cost 定义为 1 和其他相关。

数据库收集表统计信息,以便了解每个表有多大以及列值如何分布(最常见的值及其频率、直方图、与物理位置的相关性)。 p>

要查看 PostgreSQL 如何使用所有这些数字的示例,请查看文档中的 this example。

使用默认设置,根据经验,除非选择性小于 0.2,否则索引可能无济于事。

【讨论】:

【参考方案2】:

我认为您要问的是索引的影响与列中数据的数据分布有关。这里有一堆理论。在 GENERAL 中,您会发现索引查找效率取决于索引中数据的分布情况。换句话说,如果你拉 0.01% 的表比拉 5% 的表更有效。这是因为随机磁盘 I/O 的效率始终低于顺序读取(即使在 SSD 上由于操作系统的预读缓存)。

现在这不是唯一的考虑因素。总是有关于使用索引检索集合的最佳方法的问题,尤其是在有序的情况下。你是扫描排序索引还是过滤索引然后排序?通常,您在这里假设数据在两者之间均匀分布,但如果这是一个错误的假设,您可能会得到错误的查询计划。

因此,您应该在此处查找索引cardinality 并获得查询计划的经验,尤其是当计划器出错时,您可以了解为什么会出错。

【讨论】:

以上是关于列索引的有效性是不是与列数据的熵有关的主要内容,如果未能解决你的问题,请参考以下文章

pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用iloc基于行索引位置列表筛选dataframe数据中指定位置的多个数据行

pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用set_index函数把数据列转化为行索引(keys参数指定需要被转化的层列索引)

pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用set_index函数把数据列转化为行索引(keys参数指定需要被转化的层列索引)

pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用xs函数获取行切面数据(level参数指定行层索引列表key参数指定索引值列表)

pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引使用reset_index函数把行索引重置为列数据(原来的行索名称转化为列索引的最外层)

pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引使用reset_index函数把行索引重置为列数据(原来的行索名称转化为列索引的最外层)