MySQL主键查询扫描5000x太多行

时间:2016-02-27 21:28:57

标签: mysql

我尝试使用基于PRIMARY KEY的WHERE语句运行简单的SELECT查询。我在具有32个内核和30 GB RAM的GCE实例上运行MySQL 5.7.9。 500个分区中有大约300M的记录。 99.9999%的查询来自过去2天,并且该数据完全适合内存,经过验证后我看到从磁盘读取了~0个字节。我的CPU始终固定为100%,同时运行10-20个类似的查询。

我正在跟踪一些Google搜索数据,因此rankRequestedIsPriority的每个组合有KeywordIDEXPLAIN。尽管我的主要索引是设计的,因此不需要扫描,当我查看EXPLAIN EXTENDED SELECT * FROM data.Rankings -> WHERE Requested = '2016-02-26 00:00:00' AND NOT IsPriority AND KeywordID = '7387777811691965572'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: Rankings partitions: p20160226 type: ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: const rows: 552598 filtered: 1.00 Extra: Using where 1 row in set, 2 warnings (0.01 sec) 时,它显示正在扫描552k行以返回100行。

平均而言,需要20-40秒才能从RAM返回100行,这些行由主键直接指向。我该怎么做才能加快这个问题?

CREATE TABLE `Rankings` (
  `KeywordID` char(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `Requested` timestamp NOT NULL,
  `IsPriority` tinyint(1) NOT NULL,
  `Retrieved` timestamp NOT NULL,
  `Rank` tinyint(4) NOT NULL,
  `Source` varchar(5) COLLATE utf8mb4_unicode_ci NOT NULL,
  `ExternalID` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
  `Phrase` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  // another 40 data columns of varying types
  PRIMARY KEY (`Requested`,`IsPriority`,`KeywordID`,`Rank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED
// I have about 500 daily partitions over the last 1.5 years
/*!50100 PARTITION BY RANGE ( UNIX_TIMESTAMP(Requested))
(PARTITION p20160222 VALUES LESS THAN (1456185600) ENGINE = InnoDB,
 PARTITION p20160223 VALUES LESS THAN (1456272000) ENGINE = InnoDB,
 PARTITION p20160224 VALUES LESS THAN (1456358400) ENGINE = InnoDB,
 PARTITION p20160225 VALUES LESS THAN (1456444800) ENGINE = InnoDB,
 PARTITION p20160226 VALUES LESS THAN (1456531200) ENGINE = InnoDB,
 PARTITION p20160227 VALUES LESS THAN (1456617600) ENGINE = InnoDB,
 PARTITION p20160228 VALUES LESS THAN (1456704000) ENGINE = InnoDB,
 PARTITION p20160229 VALUES LESS THAN (1456790400) ENGINE = InnoDB) */;

这是数据库表

    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">



    <bean id ="HibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"   >
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="checkWriteOperations" value="false"/>  
   </bean>


        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">
        <ref bean= "dataSource"/>
        </property>
        <property name="hibernateProperties">
        <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        </props>
        </property>

       <property name="mappingResources">
       <list>
       <value>/hibernate/Compte.hbm.xml</value>
       <value>/hibernate/Groupe.hbm.xml</value>
       <value>/hibernate/Utilisateur.hbm.xml</value> 

       </list>
       </property>
       </bean>





        </beans>

1 个答案:

答案 0 :(得分:5)

我怀疑NOT导致了问题。如何使用相等比较?

SELECT *
FROM data.Rankings
WHERE Requested = '2016-02-26 00:00:00' AND 
      IsPriority = 0 AND
      KeywordID = '7387777811691965572';