首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个简单的mysql查询需要2-3秒。

这个简单的mysql查询需要2-3秒。
EN

Database Administration用户
提问于 2016-11-29 05:07:25
回答 2查看 168关注 0票数 0

我使用sqlalchemy并试图对m2m表进行查询。我有一个标记,希望找到与该标记匹配的所有事件:

代码语言:javascript
复制
SELECT * FROM events 
WHERE EXISTS ( SELECT 1 FROM events_tags, tags 
               WHERE events.id = events_tags.event_id 
               AND tags.id = events_tags.tag_id 
               AND tags.id = 617)  
LIMIT 50;

这在我的网络服务器上需要2-3秒。在我的笔记本电脑上,它更快(尽管我的笔记本更强大,行更少)。web服务器在这个表中有大约30万行。

这里有一个解释:

代码语言:javascript
复制
+------+--------------------+-------------+--------+----------------+---------+---------+--------------------------+--------+-------------+
| id   | select_type        | table       | type   | possible_keys  | key     | key_len | ref                      | rows   | Extra       |
+------+--------------------+-------------+--------+----------------+---------+---------+--------------------------+--------+-------------+
|    1 | PRIMARY            | events      | ALL    | NULL           | NULL    | NULL    | NULL                     | 310172 | Using where |
|    2 | DEPENDENT SUBQUERY | tags        | const  | PRIMARY        | PRIMARY | 8       | const                    |      1 | Using index |
|    2 | DEPENDENT SUBQUERY | events_tags | eq_ref | PRIMARY,tag_id | PRIMARY | 16      | timeline.events.id,const |      1 | Using index |
+------+--------------------+-------------+--------+----------------+---------+---------+--------------------------+--------+-------------+

我有一种感觉,这很简单,但是我的google-fu让我失望了。

创建表语法:

代码语言:javascript
复制
 | events | CREATE TABLE `events` (
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   `title` varchar(255) DEFAULT NULL,
   `context` varchar(255) DEFAULT NULL,
   `text` mediumtext,
   `wikidata_id` bigint(20) DEFAULT NULL,
   `start_day` smallint(6) DEFAULT NULL,
   `start_month` smallint(6) DEFAULT NULL,
   `start_year` bigint(20) DEFAULT NULL,
   `end_day` smallint(6) DEFAULT NULL,
   `end_month` smallint(6) DEFAULT NULL,
   `end_year` bigint(20) DEFAULT NULL,
   `is_number` tinyint(1) DEFAULT NULL,
   `version` int(11) DEFAULT NULL,
   `number` bigint(20) DEFAULT NULL,
   `start_name` varchar(255) DEFAULT NULL,
   `end_name` varchar(255) DEFAULT NULL,
   `subject_title` varchar(255) DEFAULT NULL,
   `object_title` varchar(255) DEFAULT NULL,
   `created_at` datetime DEFAULT NULL,
   `updated_at` datetime DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=327132 DEFAULT CHARSET=utf8 |

编辑:我的错,它错过了“从事件”-我想我想知道我会想要一个索引,我会想在"id“列,其中应该有一个索引。

EN

回答 2

Database Administration用户

发布于 2016-11-29 18:30:12

许多简化和加速:

代码语言:javascript
复制
SELECT e.*
    FROM ( SELECT DISTINCT event_id
             FROM events_tags
             WHERE tag_id = 617 ) AS et
    JOIN events  AS e  ON e.id = et.event_id
ORDER BY ???  -- else get random 50??
LIMIT 50;

events_tags闻起来有很多种:很多映射表。可以通过遵循这些提示来改进它。

票数 1
EN

Database Administration用户

发布于 2016-11-30 02:09:38

就像另一个变体一样,对于需要提取事件的常见情况,例如标记名称:

代码语言:javascript
复制
SELECT 
    events.*, 
    tags.tag_name 
FROM 
    events FORCE INDEX (PRIMARY)
INNER JOIN events_tags ON events.id = events_tags.event_id
INNER JOIN tags ON tags.id = events_tags.tag_id
WHERE tags.id = 617

LIMIT 50;

在某些情况下,MySQL不希望使用索引,因此我们很少帮助他(如果我们确定请求整个表的一小部分):

代码语言:javascript
复制
FROM 
    events FORCE INDEX (PRIMARY)

计划如下:

代码语言:javascript
复制
1   SIMPLE  tags            const   PRIMARY PRIMARY     4   const   1   100.00  
1   SIMPLE  events_tags     ref event_id,tag_id tag_id  5   const   3   100.00  Using where
1   SIMPLE  events          eq_ref  PRIMARY PRIMARY     4   test_db.events_tags.event_id    1   100.00  

索引-必须是,所有可比较的列都必须是相同的类型,例如events.id bigint(20) == events_tags.event_id bigint(20)

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/156618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档