加快MySQL选择查询,第一个查询比下一个查询长1000倍



我有一个简单的ISAM表,有160万个记录。典型的查询在3个索引列上具有一个Were子句,并返回10,000个左右的记录。出于这个问题的目的,我正在选择 *,并且我抛弃了订单。该表的唯一不寻常的事情是它具有1个大型非数字列Varchar(8192(。

对于我用于此问题的查询,第一个查询提交大约需要145秒,而随后提交的提交大约需要2秒钟。该表在此状态毫无价值,因为我需要做的真正的查询将需要一个小时或更长时间的第一次提交。这似乎很荒谬,无论正在完成多少磁盘I/O。当我使用我的查询的外档版本时,MySQL可以在很小的时间内写入巨大的文件...

如何修复此表?

#key_buffer_size=256M
#tmp_table_size=64M
#max_heap_table_size=64M
#myisam_sort_buffer_size=88M
#read_buffer_size=1M
#read_rnd_buffer_size=2M

回答问题:

表约为2.2GB 160万记录。

速度:不需要快速,足够快以避免在等待时死亡... 5秒现在可以接受2分钟。

通过说明返回的信息:

mysql> EXPLAIN SELECT /*+ MAX_EXECUTION_TIME(200000)*/ *  
FROM tbl_skews 
WHERE (skw_minute IN(43)) 
  AND (tday_date >= 42767 AND tday_date <= 42838) 
  AND (skw_days > -10 AND skw_days < 70);
 id     1
 select_type     SIMPLE          
 table       tbl_skews     
 partitions      NULL           
 type    ref      
 possible_keys      ndx_skews_tday_date,ndx_skews_skw_minute,ndx_skews_skw_days     
 key                     ndx_skews_skw_minute     
 key_len        2    
 ref        const     
 rows       35396    
 filtered   1.51    
 Extra           Using where 

表定义:

CREATE TABLE IF NOT EXISTS `spx_opts`.`tbl_skews` (    
`exp_true_date` INT NOT NULL,    
`exp_subndx` TINYINT NOT NULL,    
`tday_date` INT NOT NULL,    
`skw_minute` SMALLINT NOT NULL,    
`skw_TS_load` DOUBLE NOT NULL,    
`tday_days_to_next` SMALLINT NOT NULL,    
`tday_is_early_close` TINYINT NOT NULL,    
`tday_open_time` DOUBLE NOT NULL,    
`tday_close_time` DOUBLE NOT NULL,    
`prs_opar_pmod` SMALLINT NOT NULL,    
`prs_opar_yield` DOUBLE NOT NULL,    
`prs_best_yield` DOUBLE NOT NULL,    
`prs_best_pvdiv` DOUBLE NOT NULL,    
`prs_rate_libor` DOUBLE NOT NULL,    
`prs_rate_used` DOUBLE NOT NULL,    
`prs_rate_implied1` DOUBLE NOT NULL,    
`prs_rate_implied2` DOUBLE NOT NULL,    
`prs_TS_min` DOUBLE NOT NULL,    
`prs_TS_max` DOUBLE NOT NULL,    
`prs_is_exp_linked` TINYINT NOT NULL,    
`skw_is_chain_good` TINYINT NOT NULL,    
`skw_TS` DOUBLE NOT NULL,    
`skw_und_print` FLOAT NOT NULL,    
`skw_days` DOUBLE NOT NULL,    
`skw_ndx_m_pvdiv` DOUBLE NOT NULL,    
`skw_vol_atm` DOUBLE NOT NULL,    
`skw_cvix` DOUBLE NOT NULL,    
`skw_stk_vol` VARCHAR(8192) NOT NULL,    
PRIMARY KEY (`exp_true_date`, `exp_subndx`, `tday_date`, `skw_minute`),    
INDEX `ndx_skews_tday_date` (`tday_date`),    
INDEX `ndx_skews_skw_minute` (`skw_minute`),    
INDEX `ndx_skews_skw_days` (`skw_days`))    
ENGINE = MYISAM;

skw_minute, tday_date, skw_days

创建堆肥索引
create index my_idx on my_table(skw_minute, tday_date, skw_days);

您可以尝试使用索引。索引就像主键一样,但您可以在一个表中具有多个索引。

例如,如果我有以下查询

select * from users where email='christakos@gmail.com'

我必须索引电子邮件列。

您可以查看此视频以了解有关索引https://www.youtube.com/watch?v=jjnef3tpltu

的更多信息。