【问题标题】:MariaDB - Should I add index to my table?MariaDB - 我应该向我的表添加索引吗?
【发布时间】:2018-10-17 10:11:02
【问题描述】:

最近我在检查我的系统日志,发现我的一些查询非常慢。

我有一个存储用户活动的表。表结构为id (int), user (int), type (int), object (varchar), extra (mediumtext) and date (timestamp)

我也只有id (BTREE, unique)的索引。

我有以下查询的性能问题;

SELECT  DISTINCT object as usrobj
    from  ".MV15_PREFIX."useractivities
    WHERE  user='".$user_id."'
      and  type = '3'
    limit  0,1000000" 

问题是,我是否也应该将userid 索引相同?我应该遵循的最佳做法是什么?

此表已被积极使用,其中包含超过 500k+ 行。并且网站平均有 2k~ 并发用户在线。

我问这个问题的原因是我不太擅长管理数据库,而且我在另一个具有正确索引的表上查询速度很慢。

提前感谢您的建议。

旁注:

mysqltuner的结果

一般建议:

Reduce or eliminate persistent connections to reduce connection usage
Adjust your join queries to always utilize indexes
Temporary table size is already large - reduce result set size
Reduce your SELECT DISTINCT queries without LIMIT clauses
Consider installing Sys schema from https://github.com/mysql/mysql-sys

要调整的变量:

max_connections (> 768)
wait_timeout (< 28800)
interactive_timeout (< 28800)
join_buffer_size (> 64.0M, or always use indexes with joins)

(我将设置max_connections > 768,不太确定超时,就我在 Stackoverflow 中阅读的主题/建议而言,我认为我不应该增加 join_buffer_size 的大小,但我非常感谢您也能获得有关这些变量的反馈。)

编辑 - 显示索引结果;

+--------------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table              | Non_unique | Key_name        | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| ***_useractivities |          0 | PRIMARY         |            1 | id          | A         |      434006 |     NULL | NULL   |      | BTREE      |         |               |
| ***_useractivities |          1 | user_index      |            1 | user        | A         |       13151 |     NULL | NULL   |      | BTREE      |         |               |
| ***_useractivities |          1 | user_type_index |            1 | user        | A         |       10585 |     NULL | NULL   |      | BTREE      |         |               |
| ***_useractivities |          1 | user_type_index |            2 | type        | A         |       13562 |     NULL | NULL   |      | BTREE      |         |               |
+--------------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

【问题讨论】:

  • 请注意,没有 ORDER BY 的 LIMIT 是毫无意义的
  • 所有调谐器建议与关于索引的问题无关。

标签: mysql database mariadb query-performance


【解决方案1】:

大多数 PostgreSQL 索引的经验法则适用于大多数 SQL 数据库管理系统。

https://dba.stackexchange.com/a/31517/1064

所以,是的,您可能会受益于user 上的索引和type 上的索引。您可能会从 user, type 对上的索引中受益更多。

您也将从学习如何read an execution plan 中受益。

【讨论】:

  • 我不确定您所说的“为所有内容编制索引”是什么意思。每个索引都会增加数据库的大小。索引使一些select 语句更快。它们使一些insertupdatedelete 语句变慢,因为dbms 必须更改行更新索引。但是,在这种情况下,faster 并不一定意味着 fastslower 通常并不意味着 slow .索引并不是数据库管理员拥有的唯一数据库调优工具。不要猜测。制定计划,衡量,做出改变,再次衡量。
  • 谢谢你,迈克,我已经开始测试这些更改了。到目前为止,没有得到太大的改进,但理解了索引的重要性。 @WilsonHauck Explain Select 真的让我受益匪浅,我不知道我能看到它是否使用索引。添加 Mike 建议的索引后,速度更快,但不如预期。
  • @Pelin:将 Wilson Hauck 的建议粘贴到您的问题中。 (SHOW CREATE TABLE、SHOW INDEX、EXPLAIN SELECT 的输出)
  • @pelin 发布 SHOW INDEX FROM tbl_name 的文本结果;可能会显示您仍然需要(用户。类型)的覆盖索引对。如果丢失,我可以给你 ALTER 命令。
  • @pelin 我们现在可以看到您拥有 (user, type) 的复合索引。干杯。请发布 EXPLAIN SELECT .....(您的查询)的结果;我们仍然看不到 SHOW CREATE TABLE tbl_name 的结果;
【解决方案2】:

对于那个查询,其中一个是最佳的:

INDEX(user, type)
INDEX(type, user)

单独的索引 (INDEX(user), INDEX(type)) 可能没有那么好。

MySQL 的 InnoDB 只有BTree,没有Hash。无论如何,对于“点查询”,BTree 本质上与 Hash 一样好,而对于“范围”查询则要好得多。

索引tips

索引帮助SELECTsUPDATEs,有时很多。使用它们。副作用很小——例如使用了额外的磁盘空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 2011-12-22
    • 2013-03-04
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多