带有tenant_id的Mysql复合索引

Posted

技术标签:

【中文标题】带有tenant_id的Mysql复合索引【英文标题】:Mysql composite indexing with tenant_id 【发布时间】:2012-12-28 04:15:59 【问题描述】:

我们有一个多租户应用程序,它有一个包含 129 个字段的表,这些字段都可以在 WHERE 和 ORDER BY 子句中使用。我现在花了 5 天的时间试图找出最适合我们的索引策略,我获得了很多知识,但我仍然有一些问题。

1) 在创建索引时,我是否应该始终将其作为一个复合索引,其中包含tenant_id ?(所有查询在 WHERE 子句中都有 tenant_id = ?)

2) 由于所有列都可以在 WHERE 子句和 order by 子句中使用,我应该对它们都创建索引吗? (知道当我按没有索引的列进行排序时,使用大约 1,500,000 行的租户执行需要 6 秒)

3) 进行 PK (tenant_id, ID),但这不会影响到该表的联接吗?

任何有关如何处理此问题的建议将不胜感激。

====== 数据库引擎是 InnoDB

=======

结构:

ID bigint(20) auto_increment primary
tenant_id int(11)
created_by int(11)
created_on Timestamp
updated_by int(11)
updated_on Timestamp
owner_id int(11)
first_name VARCHAR(60)
last_name VARCHAR(60)
.
.
.
(some 120 other columns that are all searchable)

【问题讨论】:

在不知道表结构的情况下,很难在这个问题上给出建议。 好的,我会发布结构 什么是表引擎?如果这是 InnoDB,请确保您的 innodb_buffer_pool_size 尽可能大。如果您制作 PK tenant_id + 一些唯一 ID(除了 ID 之外,您是否有另一个唯一约束),那么它将成为任何索引的一部分,您也不需要在其他索引中拥有它,因为数据将是按tenant_id 聚集的范围查询会更快。此外,您可以按tenant_id 对表进行分区 是的,它是 InnoDB,如果我让 PK tenant_id + 一些唯一的 id 不会影响使用 ID 列的连接吗? 【参考方案1】:

对这些问题的一些简短回答。据我所知,您对使用indexes 感到困惑

考虑在列上创建索引,如果比率 -

Consideration 1-

(列的唯一条目数)/(列中的总条目数)~= 1

也就是说,特定列中的 DISTINCT 行数很高。

创建额外 index 将始终为 mysql 服务器创建开销,因此您不得为每一列创建 index您的单个​​表可以拥有的索引数量也有限制 = 每个表 64 个

现在,如果您的tenant_id 出现在所有搜索查询中,您应该将其视为indexcomposite key

前提是 -

Consideration 2 - UPDATEs 的数量少于tenant_id 上的SELECTs 的数量

Consideration 3 - 就data types 而言,indexes 应尽可能小。您不得创建varchar 64 索引http://www.mysqlperformanceblog.com/2012/08/16/mysql-indexing-best-practices-webinar-questions-followup/

Point to Note 1 - 即使您确实将任何列声明为索引,MySQL 优化器仍可能不会将其视为最佳查询执行计划。所以总是使用EXPLAIN 来了解发生了什么。 http://www.mysqlperformanceblog.com/2009/09/12/3-ways-mysql-uses-indexes/

Point to Note 2 - 你可能想cache你的搜索查询,所以记住不要在你的SELECT查询中使用不可预测的语句,例如NOW()

最后 - 制作 PK (tenant_id, ID) 不应影响表上的连接。 还有一个很棒的链接可以回答您的所有问题 - http://www.percona.com/files/presentations/WEBINAR-MySQL-Indexing-Best-Practices.pdf

【讨论】:

非常感谢。所以我应该使用 PK (tenant_id, ID) 还是只在每个索引中包含tenant_id(所有查询都包括 wheretenant_id=?) 主键的作用是找出一个唯一的行,因为那是你表中的自动 inc,你可以保留单个主键并添加 tenant_id 作为单独的索引。那里没有问题。 @redmoon7777 - 我本可以提供更多细节,但这会使这个答案太长而无法阅读。无论如何,您也可以查看有关同一主题的网络研讨会记录。 percona.com/webinars/2012-08-15-mysql-indexing-best-practices

以上是关于带有tenant_id的Mysql复合索引的主要内容,如果未能解决你的问题,请参考以下文章

关于MySQL复合索引的使用方法有哪些?

复合索引顺序 MySQL 查询

MySQL创建复合索引

MariaDB/MySQL 复合唯一索引无效

为啥 MySQL 不使用复合 WHERE IN 的索引?

mysql复合索引