带有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
出现在所有搜索查询中,您应该将其视为index
或composite key
,
前提是 -
Consideration 2
- UPDATEs
的数量少于tenant_id
上的SELECTs
的数量
Consideration 3
- 就data types
而言,indexe
s 应尽可能小。您不得创建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复合索引的主要内容,如果未能解决你的问题,请参考以下文章