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

MySQL查询优化-提高速度和效率

嵇光临
2023-03-14

我想在数据库中得到一些电子邮件,每个电子邮件都有一个状态。所有可能的状态都是一个表中的stock,在该表中它们都有权限(如show、edit、delete等)。那些电子邮件不是用户通过一个站点的权限,而是一个用户添加的电子邮件列表。

下面是表的结构:

电子邮件表

    CREATE TABLE IF NOT EXISTS `email__email` (
    `email_id` int(11) NOT NULL AUTO_INCREMENT,
    `created` timestamp NULL DEFAULT NULL,
    `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `user_fk` int(11) NOT NULL,
    `status_fk` tinyint(2) NOT NULL,
    `language` enum('fr','en') COLLATE utf8_unicode_ci DEFAULT NULL,
    `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `firstName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `lastName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
    `companyName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `gender` enum('f','m') COLLATE utf8_unicode_ci DEFAULT NULL,
    PRIMARY KEY (`email_id`),
    UNIQUE KEY `user_email` (`user_fk`,`email`),
    KEY `user_fk` (`user_fk`),
    KEY `created` (`created`),
    KEY `status_fk` (`status_fk`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3031492 ;

状态表

    CREATE TABLE IF NOT EXISTS `email__status` (
    `status_id` int(11) NOT NULL AUTO_INCREMENT,
    `name_fr` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
    `name_en` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
    `description_fr` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
    `description_en` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
    `permShow` tinyint(1) NOT NULL DEFAULT '0',
    `permSend` tinyint(1) NOT NULL DEFAULT '0',
    `permEdit` tinyint(1) NOT NULL DEFAULT '0',
    `permDelete` tinyint(1) NOT NULL DEFAULT '0',
    `permImport` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`status_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ;
    SELECT EE.*, ES.name_fr AS statusName, ES.description_fr AS statusDescription, ES.permShow, ES.permSend, ES.permEdit, ES.permDelete, ES.permImport
    , (SELECT GROUP_CONCAT(CONVERT(CONCAT(GC.name, '~', GC.group_id), CHAR(255)) SEPARATOR ',') FROM `group` GC INNER JOIN group_email GEC ON GEC.group_fk = GC.group_id WHERE GEC.email_fk = EE.email_id AND GC.deleted = 0) AS groups
    FROM `email__email` EE
    INNER JOIN email__status ES ON EE.status_fk = ES.status_id
    WHERE 1 = 1
    AND EE.user_fk = 54
    AND ES.permShow = 1
    ORDER BY EE.email_id DESC LIMIT 15


    EXTRA   ID  KEY KEY_LEN POSSIBLE_KEYS   REF ROWS    SELECT_TYPE TABLE   TYPE
    Using temporary; Using filesort 1   user_email  4   user_email,user_fk,status_fk    const   180681  PRIMARY EE  ref
    Using where; Using join buffer  1   [empty string]  [empty string]  PRIMARY [empty string]  6   PRIMARY ES  ALL
    Using index 2   email_fk    4   group_email,group_fk,email_fk   mailing_dev.EE.email_id 1   DEPENDENT SUBQUERY  GEC ref
    Using where 2   PRIMARY 4   PRIMARY mailing_dev.GEC.group_fk    1   DEPENDENT SUBQUERY  GC  eq_ref
    SELECT EE.*
    , (SELECT GROUP_CONCAT(CONVERT(CONCAT(GC.name, '~', GC.group_id), CHAR(255)) SEPARATOR ',') FROM `group` GC INNER JOIN group_email GEC ON GEC.group_fk = GC.group_id WHERE GEC.email_fk = EE.email_id AND GC.deleted = 0) AS groups
    FROM `email__email` EE
    WHERE 1 = 1 
    AND EE.user_fk = 54
    AND EXISTS(SELECT permShow FROM email__status WHERE status_id = EE.status_fk AND permShow = 1)
    ORDER BY EE.email_id DESC LIMIT 15


    EXTRA   ID  KEY KEY_LEN POSSIBLE_KEYS   REF ROWS    SELECT_TYPE TABLE   TYPE
    Using where 1   PRIMARY 4   user_email,user_fk  [empty string]  270 PRIMARY EE  index
    Using where 3   PRIMARY 4   PRIMARY mailing_dev.EE.status_fk    1   DEPENDENT SUBQUERY  email__status   eq_ref
    Using index 2   email_fk    4   group_email,group_fk,email_fk   mailing_dev.EE.email_id 1   DEPENDENT SUBQUERY  GEC ref
    Using where 2   PRIMARY 4   PRIMARY mailing_dev.GEC.group_fk    1   DEPENDENT SUBQUERY  GC  eq_ref

谢谢

共有1个答案

麻阳
2023-03-14

email__email.status_fk是一个tinyint,但email__status.status_id是一个int(11)。

这可能是污损了你的内部连接。更改一个或另一个数据类型,然后重试。

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

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

  • 本文向大家介绍为什么索引能提高查询速度?相关面试题,主要包含被问及为什么索引能提高查询速度?时的应答技巧和注意事项,需要的朋友参考一下 以下内容整理自: 地址: https://juejin.im/post/5b55b842f265da0f9e589e79 作者 :Java3y 先从 MySQL 的基本存储结构说起 MySQL的基本存储结构是页(记录都存在页里边): 各个数据页可以组成一个双向链表

  • 5.13.1. 查询高速缓冲如何工作 5.13.2. 查询高速缓冲SELECT选项 5.13.3. 查询高速缓冲配置 5.13.4. 查询高速缓冲状态和维护 查询缓存存储SELECT查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。 如果你有一个不经常改变的表并且服务器收到该表的大量相同查询,查询缓存在这样的应用环境中十

  • 问题内容: 一个供您所有MySQL专家使用的技巧:-) 我有以下查询: 订单表= 80,900行 产品表= 125,389行 o.id和p.order_id已建立索引 该查询大约需要6秒钟才能完成-太长了。我正在寻找一种优化它的方法,可能使用临时表或其他类型的联接。恐怕我对这两个概念的理解还很有限。 谁能建议我优化此查询的方法? 问题答案: 首先,我将使用其他样式的语法。 已经有20年的睡眠时间了

  • 本文向大家介绍SQL Server 使用join all优化 or 查询速度,包括了SQL Server 使用join all优化 or 查询速度的使用技巧和注意事项,需要的朋友参考一下 比如:,master,test, 表示 该用户为 test 的下级代码,test登录后可以看到 test名下的业务和所有下级代理的业务。相关表的结构如下: 优化前的SQL语句如下: 不使用 or 单独查询时,都不