ThinkPHP5查询当前表引擎,以及InnoDB表引擎下count(*)查询效率低的问题



今天新开发的功能上线之后出现了查询效率极其低下的问题,查询日志后发现问题出在代码内的大量的count()查询上,最严重时一条简单的count()查询执行时间长达120多秒!

针对这个问题请教前辈后被告知原因:InnoDB引擎下的count()语句会在实时查询表中的所有数据后返回总数所以效率较低,而MyISAM引擎则是直接返回表内存储的行记录信息所以效率较高。因为我本地的数据库引擎为MyISAM而线上的阿里云数据库服务器引擎为InnoDB所以出现了这种本地环境与线上环境查询效率差距极大的问题。

并且前辈也给出了指导意见:因为InnoDB引擎的主键索引通常为聚簇索引,为了保证效率可以新建一个辅助索引用于为count()查询指定字段。经尝试后使用新的辅助索引字段来进行count()查询效率确实大大提升。



这里附上查询当前表引擎并判断是使用主键字段还是使用辅助索引字段进行count()查询的相关代码。

框架使用的是ThinkPHP5,可以根据自己的状况自行调整代码。

function xmsb_getCountField($tableName)
{
    $dataBase = config(‘database.database‘);

    $tableDDL = Db::query("SHOW TABLE STATUS FROM `{$dataBase}` WHERE name = ‘{$tableName}‘"); // 获取表信息
    $engine = strtolower($tableDDL[0][‘Engine‘]); // 取得表引擎信息

    // 取得主键字段
    $pk = DB::getTableInfo($tableName, ‘pk‘);
    if(is_array($pk)) $pk = $pk[0];

    // 若表引擎为InnoDB则判断是否存在非主键索引
    if($engine == ‘innodb‘)
    {
        $indexs = Db::query("SHOW INDEX FROM {$tableName}");
        $key = $pk;
        foreach($indexs as $index)
        {
            // 若存在非主键索引,则返回该索引对应的字段
            if($index[‘Key_name‘] != ‘PRIMARY‘)
            {
                $key = $index[‘Column_name‘];
                break;
            }
        }

        return $key;
    }
    else
    {
        // 非InnoDB引擎则直接返回主键字段
        return $pk;
    }
}

$count = Db::name(‘数据表名‘) -> count(xmsb_getCountField(‘完整数据表名‘));

原文地址:https://www.cnblogs.com/XiaoMingBlingBling/p/12035911.html

时间: 2024-11-10 13:00:15

ThinkPHP5查询当前表引擎,以及InnoDB表引擎下count(*)查询效率低的问题的相关文章

MYSQL MYISAM引擎与INNODB引引擎的区别

MYISAM和INNODB是MYSQL数据库的两个主要引擎,MYISAM是MYSQL5.5版本之前的默认的引擎,而INNODB是MYSQL 5.5版本默认引擎. 两个引擎的区别如下: 事务处理 INNODB支持事务处理功能,事务具有以下4个属性,通常简称为事务的ACID属性. 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行. 一致性(Consisten):在事务开始和完成时,数据都必须保持一致状态.这意味着所有相关的数据规则都必须应用于事务的修

InnoDB存储引擎的表空间文件,重做日志文件

存储引擎文件:因为MySQL表存储引擎的关系,每个存储引擎都会有自己的文件来保存各种数据.这些存储引擎真正存储了数据和索引等数据. 表空间文件 InnoDB存储引擎在存储设计上模仿了Oracle,将存储的数据按表空间进行存放.默认配置下,会有一个初始化大小为10MB.名为ibdata1的文件.该文件就是默认的表空间文件(tablespace file).你可以通过参数innodb_data_file_path对其进行设置.格式如下: innodb_data_file_path=datafile_

MySQL InnoDB存储引擎之表(一)

主要介绍InnoDB存储引擎表的逻辑存储以及实现.重点介绍数据在表中是如何组织和存放的. 1.索引组织表(index organized table) 在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表叫索引组织表.在InnoDB存在引擎表中,每张表都有个主键(Primary key),如果在创建表时没有显示定义主键,则会按照如下方式选择或者创建主键:a.判定是否有非空的唯一索引(unique not null),如果有则该列即为主键.若果有多个,则选择建表是第一个定义的非

InnoDB存储引擎表的逻辑存储结构

1.索引组织表: 在InnoDB存储引擎中,表都是依照主键顺序组织存放的.这样的存储方式的表称为索引组织表,在innodb存储引擎表中,每张表都有主键.假设创建的时候没有显式定义主键,则InnoDB会依照例如以下方式选择或者创建主键: 1). 首先推断表中是否有非空的唯一索引,假设有.则该列就为主键. 2).   假设不符合上述条件,则innodb会自己主动创建一个6字节大小的指针 假设表中有多个非空唯一索引时,InnoDB将选择建表时第一个定义的非空唯一索引为主键,通过_rowid能够显示表的

[MySQL Reference Manual]14 InnoDB存储引擎

14 InnoDB存储引擎 14 InnoDB存储引擎... 1 14.1 InnoDB说明... 5 14.1.1 InnoDB作为默认存储引擎... 5 14.1.1.1 存储引擎的趋势... 5 14.1.1.2 InnoDB变成默认存储引擎之后... 5 14.1.1.3 InnoDB表好处... 6 14.1.1.4 InnoDB表最佳实践... 6 14.1.1.5 InnoDB表提升... 6 14.1.1.6 InnoDB作为默认存储引擎测试... 6 14.1.1.7 验证In

浅谈MYSQL引擎之INNODB引擎

MYSQL 常用的引擎主要有一下几种,MRG_MYISAM .CSV .MyISAM.InnoDB.MEMORY ,NDB,其中MyISAM.InnoDB是mysql最常用的存储引擎,今天主要讨论 InnoDB引擎. 一.什么是InnoDB引擎 InnoDB引擎是MYSQL数据库的另一个重要的额存储引擎,正成为目前MYSQL AB所有发行新版的标准,被包含在所有二进制安装包里. 和其他的存储引擎相比,InnoDB引擎的优点支持兼容ACID的事物,以及参数完整性(即对外建的支持). MYSQL5.

MySQL InnoDB 存储引擎探秘

在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中.从MySQL5.5.8开始,InnoDB成为其默认的存储引擎.InnoDB存储引擎支持事务.其设计目标主要是面向OLTP的应用,主要特点有:支持事务.行锁设计支持高并发.外键支持.自动崩溃恢复.聚簇索引的方式组织表结构等. 体系架构 InnoDB存储引擎是由内存池.后台线程.磁盘存储三大部分组成. 线程 InnoDB 使用的是多线程模型, 其后台有多个不同的线程负责处理不同的任务 Master Thread Master T

mysql共享表空间和独立表空间

innodb表的数据结构 innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等. 对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间. 什么是共享表空间和独占表空间 共享表空间以及独占表空间都是针对数据的存储方式而言的. 共享表空间:  某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下. 默认的文件名为:ibdata1  初始化为10M. 独占表空间:  每一个表都将会生成以独立的文件方式

mysql事务表和非事务表在binlog日志的不同处理

mysql的binlog日志是维系mysql主从同步的重要媒介.binlog日志对SQL记录策略,直接影响到主从之间的数据一致性.接下来我们来实验下,看看mysql对事务表和非事务表的DML操作,binlog是如何记录的. 实验环境:mysql官方社区版5.7.18, 操作系统centos7.3,binlog日志格式采用row格式. 1.创建Myisam表b和Innodb表a. CREATE TABLE `a` (   `id` int(11) NOT NULL,   `name` varcha