使用ORDER BY和LIMIT时查询速度很慢?

时间:2012-08-21 10:08:57

标签: mysql sql-order-by limit

订购时,以下查询需要10秒钟才能完成。没有订单,它在0.0005秒完成。我已经在字段“sku”,“vid”和“timestamp”上有索引。我在这张表中有超过200,000条记录。请帮忙,使用order by时查询有什么问题。

SELECT i.pn,i.sku,i.title, fl.f_inserted,fl.f_special, fl.f_notinserted
FROM inventory i 
LEFT JOIN inventory_flags fl ON fl.sku = i.sku AND fl.vid = i.vid
WHERE i.qty >=2 ORDER BY i.timestamp  LIMIT 0,100;

-- --------------------------------------------------------

--
-- Table structure for table `inventory`
--

CREATE TABLE IF NOT EXISTS `inventory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pn` varchar(60) DEFAULT NULL,
  `sku` varchar(60) DEFAULT NULL,
  `title` varchar(60) DEFAULT NULL,
  `qty` int(11) DEFAULT NULL,
  `vid` int(11) DEFAULT NULL,
  `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `vid` (`vid`),
  KEY `sku` (`sku`),
  KEY `timestamp` (`timestamp`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Table structure for table `inventory_flags`
--

CREATE TABLE IF NOT EXISTS `inventory_flags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `f_inserted` tinyint(1) DEFAULT NULL,
  `f_notinserted` tinyint(1) DEFAULT NULL,
  `f_special` tinyint(1) DEFAULT NULL,
  `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `sku` varchar(60) DEFAULT NULL,
  `vid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `vid` (`vid`),
  KEY `sku` (`sku`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

EXPLANE RESULT:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  fl  system  vid,sku NULL    NULL    NULL    0   const row not found
1   SIMPLE  i   index   NULL    timestamp   5   NULL    10  Using where

3 个答案:

答案 0 :(得分:4)

不要在列上添加单独的索引,而是需要在表上放置multicolumn index,因为在连接条件中使用同一个表中的多个列。

包含WHERE子句中的列后,还包括composite indexORDER BY子句中使用的列。 尝试添加流动索引并使用EXPLAIN测试它们:

ALTER TABLE ADD INDEX ix_if inventory_flags(sku, vid);
ALTER TABLE ADD INDEX ix_i inventory(sku, qty, timestamp);

还尝试避免查询中的DISTINCT子句,它等同于GROUP BY子句,如果仍然需要它,则考虑添加覆盖索引。

答案 1 :(得分:2)

如果sku对每个广告资源项都是唯一的,那么请将其定义为UNIQUE - 它会加快速度。 (或skuvid的组合 - 在这种情况下定义复合索引。)

你为什么要做SELECT DISTINCT?绝大多数时间使用DISTINCT表示您的查询或表结构错误。

由于它是DISTINCT,而sku不是UNIQUE,因此无法使用时间戳上的索引加快速度,因此必须对包含200,000条记录的表进行排序 - 它甚至不能使用数量上的索引加速这部分。

PS。 Omesh也有一些很好的建议。

答案 2 :(得分:0)

您可以使用force index(index_key)。尝试一下,你会在解释查询中看到mysql现在将使用键索引时按'

排序