当前位置: 首页 > 知识库问答 >
问题:

大型表的MySQL查询优化

艾心远
2023-03-14

我有一个需要50秒的查询

SELECT `security_tasks`.`itemid` AS `itemid`
FROM `security_tasks`
INNER JOIN `relations` ON (`relations`.`user_id` = `security_tasks`.`user_id` AND    `relations`.`relation_type_id` = `security_tasks`.`relation_type_id` AND `relations`.`relation_with` = 3001 )  

security_tasks中的记录=841321 relations中的记录=234254

CREATE TABLE `security_tasks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `itemid` int(11) DEFAULT NULL,
  `relation_type_id` int(11) DEFAULT NULL,
  `Task_id` int(2) DEFAULT '0',
  `job_id` int(2) DEFAULT '0',
  `task_type_id` int(2) DEFAULT '0',
  `name` int(2) DEFAULT '0'
  PRIMARY KEY (`id`),
  KEY `itemid` (`itemid`),
  KEY `relation_type_id` (`relation_type_id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1822995 DEFAULT CHARSET=utf8;

CREATE TABLE `relations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `relation_with` int(11) DEFAULT NULL,
  `relation_type_id` int(11) DEFAULT NULL,
  `manager_level` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `relation_with` (`relation_with`),
  KEY `relation_type_id` (`relation_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1082882 DEFAULT CHARSET=utf8;

我能做些什么让它快一点,比如快1秒或2秒

id select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  relations   ref user_id,relation_with,relation_type_id  relation_with   5   const   169 Using where
1   SIMPLE  security_tasks  ref relation_type_id,user_id    user_id 5   transparent.relations.user_id   569 Using where

有什么想法吗?

共有1个答案

顾单弓
2023-03-14

稍微调整你的复合指数,不要只做两个,而是所有三个部分

ALTER TABLE relations ADD INDEX(user_id、relation_type_id、relation_with)

索引不仅必须位于联接的列上,而且应该基于联接的列以及查询条件所涉及的任何其他有意义的内容(在合理的情况下,需要时间来了解更多的效率)。因此,在建议的情况下,您知道用户和类型上的联接,但也是特定于与...因此将其添加到同一索引中。

SELECT 
      st.itemid
   FROM 
      security_tasks st
         INNER JOIN relations r
            ON st.user_id = r.user_id 
            AND st.relation_type_id = r.relation_type_id
            AND r.relation_with = 3001
 类似资料:
  • 在MySQL数据库中,我遇到了一个问题,当我在执行一个JOIN查询时,发现查询性能显著降低,特别是在两个大表之间进行JOIN操作时。我的两个表分别是orders(订单表,大约有1000万条记录)和customers(客户表,大约有500万条记录),它们通过customer_id字段相关联。我已经为这两个表的customer_id字段建立了索引,但是在执行如下JOIN查询时,耗时仍然较长: 运行环境

  • 问题内容: 我有一张大桌子: 所有请求中有90%与最近2-3天的订单有关,例如: 如何提高性能? 我知道分区,但是现有行呢?看来我需要每2-3天手动创建表格。 问题答案: 一个 部分,多列索引 上与伪状态将有助于(很多)。需要不时地重新创建以保持性能。 注意,如果表不是很大,则可以在很大程度上简化和使用普通的多列索引。 或者考虑在Postgres 12或更高版本(功能最终成熟的地方)中进行表分区。

  • 问题内容: 这就是整个查询… 如果… 和… 有明显的理由吗? 正在服用? 扩展说明 问题答案: 您可以始终使用EXPLAIN或EXPLAIN EXTENDED 来查看MySql对查询所做的操作 您也可以用稍微不同的方式编写查询,是否尝试过以下方法? 看看效果如何会很有趣。我希望它会更快,因为目前,我认为MySql将为您拥有的每个节目运行内部查询1(这样一个查询将运行多次。联接应该更有效。) 如果希

  • 有ci_trail表,字段为:id, uid(用户id), address(地址), create_time 记录人的定位轨迹,此表大概有100w条数据。想查询每个人最新的一条地址信息。使用如下sql: 查询计划如下图: 可见进行了全表扫描,查询效率很低,请问这种情况应该如何优化sql? 已解决 方案1: 方案2: 先将子查询中的id查询出来,然后将id的结果集逗号隔开填充到in中。因为in的内容

  • 主要内容:概述,一、关联查询优化,1.左(右)外连接,2.内连接,3.JOIN语句原理,4.JOIN小结,5.Hash Join,二、子查询优化,三、排序优化,四、GROUP BY优化,五、优先考虑覆盖索引,六、使用前缀索引,七、索引下推ICP,八、其他查询优化,1.COUNT(*)与COUNT(具体字段)效率,2.不使用SELECT *,3.LIMIT 1优化,4.多使用commit概述 数据库调优的方式有多种: 建立索引、充分利用到索引、不让索引失效 对SQL语句进行优化 调优如缓冲、线程数

  • 问题内容: 我有以下查询: 查询在具有25.000行的数据库表上执行。该查询的执行时间约为40秒。结果将显示在网页上,因此等待40秒以获取结果并不是很好。 有没有一种方法可以执行此查询并保存其输出?因为如果每天晚上执行此查询就足够了。 最好的方法是什么?我应该创建一个cronjob并执行此查询并将结果写入数据库吗?或者,还有更好的方法? 或者我可以优化此查询以使其更快? 问题答案: 我认为所有这些