【问题标题】:Hibernate query execution issue休眠查询执行问题
【发布时间】:2013-04-08 14:10:34
【问题描述】:

我在查询执行中遇到了一些问题,这是我的情况:

我有两个表 log 有 20 万条记录和 logrecords 有 60 万条记录

日志表中的单个日志记录可以在日志记录表中有多个日志消息,我的数据库架构如下

日志

CREATE TABLE `log` (                           
       `logid` varchar(50) NOT NULL DEFAULT '',         
       `creationtime` bigint(20) DEFAULT NULL,            
       `serviceInitiatorID` varchar(50) DEFAULT NULL,   
       PRIMARY KEY (`logid`),                           
       KEY `idx_creationtime_wsc_log` (`creationtime`)  
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1

日志记录

CREATE TABLE `logrecords` (                                                 
              `logrecordid` varchar(50) NOT NULL DEFAULT '',                                
              `timestamp` bigint(20) DEFAULT NULL,                                          
              `message` varchar(8000) DEFAULT NULL,                                         
              `loglevel` int(11) DEFAULT NULL,                                              
              `logid` varchar(50) DEFAULT NULL,                                             
              `indexcolumn` int(11) DEFAULT NULL,                                           
              PRIMARY KEY (`logrecordid`),                                                  
              KEY `indx_logrecordid_message_logid` (`logrecordid`,`message`(767),`logid`),  
              KEY `logid` (`logid`),                                                        
              KEY `indx_message` (`message`(767))                                           
            ) ENGINE=InnoDB DEFAULT CHARSET=latin1    

hibernate 创建的查询是这样的

select this_.logid as logid4_1_, this_.loglevel as loglevel4_1_, this_.creationtime as creation3_4_1_,this_.serviceInitiatorID as service17_4_1_, this_.logtype as logtype4_1_,logrecord1_.logrecordid as logrecor1_3_0_, logrecord1_.timestamp as timestamp3_0_, logrecord1_.message as message3_0_, logrecord1_.loglevel as loglevel3_0_, logrecord1_.logid as logid3_0_, logrecord1_.indexcolumn as indexcol6_3_0_ from log this_ inner join wsc_logrecords logrecord1_ on this_.logid=logrecord1_.logid where (1=1) and (1=1) and logrecord1_.message like 'SecondMessage' order by this_.creationtime desc limit 25

大约需要 7313ms 来执行

查询解释就像

但是当我执行下面的查询时,执行大约需要 15 分钟

select count(*) as y0_ from log this_ inner join logrecords logrecord1_ on this_.logid=logrecord1_.logid where (1=1) and (1=1) and lower(logrecord1_.message) like 'SecondMessage' order by this_.creationtime desc limit 25

对于上面的查询解释就像

我正在使用 MySQl 数据库。我认为索引或其他一些我无法识别的问题

任何解决方案将不胜感激。

【问题讨论】:

  • 如果你写解释before查询,它告诉你什么?
  • 嗨,Shervin,我已经用查询解释更新了我的问题

标签: mysql database hibernate


【解决方案1】:

当您使用lower(logrecord1_.message) like 'SecondMessage' 而不是普通的logrecord1_.message like 'SecondMessage' 时,数据库引擎将停止使用logrecord1_.message 上的索引。

您可以通过创建一个基于函数的索引来克服这个问题,该索引使用lower(logrecord1_.message) 代替logrecord1_.message

【讨论】:

  • MySQL 不支持基于函数的索引,如下所述:stackoverflow.com/questions/10595037/… 但是,我认为通过对列消息使用不区分大小写的排序规则,我认为 lower() 函数变得多余。
  • @Marcellus:把它写下来作为答案。我会删除这个答案,因为它没有帮助。
  • 我也尝试在计数查询中使用 logrecord1_.message 之类的 'SecondMessage' 而不是使用 lower(logrecord1_.message) 之类的 'SecondMessage' 但没有任何改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
相关资源
最近更新 更多