MySQL长期查询时间

时间:2015-03-10 16:57:51

标签: mysql database performance innodb

我有一个网站,它对数据库有两个主要查询,这些查询在第一次运行时非常慢,经过一些测试后似乎是MySQL的一个问题。如果我在运行查询时直接在Sequal Pro中运行查询,第一次运行最多可能需要4秒才能运行相同的查询需要大约60毫秒,查询时间与我们服务器上的查询时间大致相同,让我觉得它不是服务器问题。

不完全确定增加缓冲池大小会有太大帮助,因为潜在查询组合的数量可能大约为800K。

数据库中的表是innodb,两个查询都访问具有52K记录的同一个表,我需要的大部分信息都被组合成一个被索引的“搜索字段”字段。

仅对查询中使用的字段或主/外键进行索引。

我尝试将内部联接更改为主查询的“where”中的select语句,但这不会使查询更快。

查询

查询1

SELECT 
  `item_attribute`.`attribute_id` AS `attribute_id`,
  `attribute_value_id` AS `attribute_value_id`,
  `collection_attribute`.`title` AS `ca_title`,
  `collection_attribute`.`type` AS `ca_type`,
  `collection_attribute`.`is_collapsible` AS `ca_is_collapsible`,
  `collection_attribute`.`orderindex` AS `ca_orderindex`,
  `collection_attribute`.`multi_select` AS `ca_multi_select`,
  `item_attribute`.`item_id` AS `item_id`,
  `product`.`id` AS `product_id` 
  FROM `item_attribute`
  INNER JOIN `item` ON item.id = item_attribute.item_id
  INNER JOIN `product` ON product.id = item.product_id
  INNER JOIN `collection_attribute` ON item_attribute.attribute_id = collection_attribute.attribute_id
  INNER JOIN `attribute_value` ON attribute_value.id = item_attribute.attribute_value_id 
  WHERE ((`product`.`searchfilter` LIKE '%c:35∆%') AND (`collection_attribute`.`collection_id`='35')) AND (`attribute_value`.`active`=1)
  GROUP BY `attribute_value_id`

查询2

SELECT DISTINCT `item_attribute`.`attribute_id` AS `attribute_id`,
  GROUP_CONCAT(item_attribute.attribute_value_id SEPARATOR \"-\") AS `attribute_value`,
  GROUP_CONCAT(attribute_value.title SEPARATOR \" - \") AS `title`
  FROM `item_attribute`
  LEFT JOIN `item` ON item.id = item_attribute.item_id 
  LEFT JOIN `attribute` ON attribute.id = item_attribute.attribute_id 
  LEFT JOIN `attribute_value` ON attribute_value.id = attribute_value_id 
  WHERE (`item`.`product_id`='894') AND (`attribute`.`is_option`=1) 
  GROUP BY `attribute_id`, `item_id`

表格结构

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  `sku` varchar(20) NOT NULL,
  `active` tinyint(1) DEFAULT '0',
  `orderindex` int(2) DEFAULT '-1',
  `search` varchar(255) DEFAULT NULL,
  `searchfilter` varchar(255) DEFAULT NULL,
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  `protected` tinyint(1) DEFAULT '0',
  `description` varchar(512) DEFAULT NULL,
  `type_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `product_ibfk_1` (`type_id`),
  KEY `searchfilter` (`searchfilter`),
  CONSTRAINT `product_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `attribute_value` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1882 DEFAULT CHARSET=utf8;

-

CREATE TABLE `collection_attribute` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `collection_id` int(11) DEFAULT NULL,
  `attribute_id` int(11) DEFAULT NULL,
  `title` varchar(512) NOT NULL,
  `slug` varchar(512) NOT NULL,
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  `active` tinyint(1) DEFAULT '0',
  `orderindex` int(2) DEFAULT '-1',
  `search` varchar(255) DEFAULT NULL,
  `searchfilter` varchar(255) DEFAULT NULL,
  `protected` tinyint(1) DEFAULT '0',
  `is_collapsible` tinyint(1) DEFAULT '0',
  `type` enum('icon','checkbox','checkboxIcon','image') DEFAULT NULL,
  `multi_select` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `collection_attribute_ibfk_1` (`collection_id`),
  KEY `collection_attribute_ibfk_2` (`attribute_id`),
  CONSTRAINT `collection_attribute_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collection` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `collection_attribute_ibfk_2` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=140 DEFAULT CHARSET=utf8;

-

    CREATE TABLE `item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `slug` varchar(255) NOT NULL,
  `title` varchar(255) NOT NULL,
  `pattern_code` varchar(32) NOT NULL,
  `tom_code` varchar(32) NOT NULL,
  `navision_code` varchar(32) NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  `active` tinyint(1) DEFAULT '0',
  `orderindex` int(2) DEFAULT '-1',
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  `search` varchar(1024) DEFAULT NULL,
  `searchfilter` varchar(255) DEFAULT NULL,
  `product_id` int(11) DEFAULT NULL,
  `protected` tinyint(1) DEFAULT '0',
  `pattern_series` varchar(255) DEFAULT NULL,
  `pattern_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `item_ibfk_1` (`product_id`),
  KEY `searchfilter` (`searchfilter`),
  KEY `product_id` (`product_id`),
  KEY `pattern_id` (`pattern_id`),
  CONSTRAINT `item_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `item_ibfk_2` FOREIGN KEY (`pattern_id`) REFERENCES `pattern_series` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=50060 DEFAULT CHARSET=utf8;

-

CREATE TABLE `item_attribute` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `item_id` int(11) NOT NULL,
  `attribute_id` int(11) NOT NULL,
  `attribute_value_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `attribute_id` (`attribute_id`),
  KEY `attribute_value_id` (`attribute_value_id`),
  KEY `item_id` (`item_id`),
  CONSTRAINT `item_attribute_ibfk_1` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `item_attribute_ibfk_2` FOREIGN KEY (`attribute_value_id`) REFERENCES `attribute_value` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `item_attribute_ibfk_3` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=857111 DEFAULT CHARSET=utf8;

-

CREATE TABLE `attribute_value` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `slug` varchar(255) NOT NULL,
  `code` varchar(255) DEFAULT NULL,
  `title` varchar(255) NOT NULL,
  `active` tinyint(1) DEFAULT '0',
  `orderindex` int(2) DEFAULT '-1',
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  `search` varchar(255) DEFAULT NULL,
  `searchfilter` varchar(255) DEFAULT NULL,
  `attribute_id` int(11) DEFAULT NULL,
  `protected` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3471 DEFAULT CHARSET=utf8;

-

CREATE TABLE `attribute` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  `code` varchar(255) DEFAULT NULL,
  `is_option` tinyint(1) DEFAULT '0',
  `searches` tinyint(1) DEFAULT '0',
  `option_type` enum('dropdown','switch','fingersizes') DEFAULT NULL,
  `option_label` varchar(32) DEFAULT NULL,
  `active` tinyint(1) DEFAULT '0',
  `orderindex` int(2) DEFAULT '-1',
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  `search` varchar(255) DEFAULT NULL,
  `searchfilter` varchar(255) DEFAULT NULL,
  `protected` tinyint(1) DEFAULT '0',
  `option_requires` int(11) DEFAULT NULL,
  `option_depends` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `is_option` (`is_option`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;

有关如何改善初始查询时间的任何建议都会很棒

提前致谢:)

- 编辑 -

EXPLAIN SELECT查询1 Explain Select

EXPLAIN SELECT查询2 Explain select

1 个答案:

答案 0 :(得分:2)

首次启动服务器后执行查询时,没有任何内容是缓存,因此查询需要从磁盘中获取内容。由于缓存,访问相同表的相同部分的所有后续查询将更快。这是“正常的”。

如果您启用了“查询缓存”(默认情况下可能已启用),那么第二次运行完全相同的查询时,它将立即查找查询缓存的结果。 “完全”我的意思是说空白空间没有变化。关闭查询缓存几乎所有“生产”服务器都会更好。

innodb_buffer_pool_size应该是可用内存的70%左右。更改该值不会影响针对冷缓存的SELECT,但可能会帮助/损害后续运行。这似乎与您的情况无关,因为第二次运行非常快。

请提供EXPLAIN SELECT ...,以便我们了解优化程序如何决定执行它们。

LIKE '%c:35∆%' - 由于领先的外卡而无法使用索引。

什么是item_ids

item_attribute是一种EAV架构模式。太糟糕了。这两个查询都很丑陋,可扩展性也很糟糕。它可以帮助某些摆脱id并从其他字段的合适组合中创建复合PRIMARY KEY。希望使用与数据聚类的PRIMARY KEY,而不是必须从辅助键反弹。 More discussion of EAV

假设基数较低,则可能永远不会使用索引:
KEY is_optionis_option