我有一个存储产品的数据库。两个最大的表是我的产品表和图像表。 产品:~19,000行
图片:~34.000行
分类:~60行
原始类别:~1200行
品牌:700行
(其他表格只有几行)
我还有一个包含品牌,原始类别,静态类别的表格(原始类别映射到静态类别)。
我创建了一个Product VIEW来收集我需要的数据,如下所示:
CREATE OR REPLACE VIEW `jos_clothes_view_products` AS
SELECT tbl.*, r.name AS reseller, b.name AS brand, rcat.raw_name AS cats_raw, cats1.name AS cat1, cats1.slug AS catslug1, cats2.name AS cat2, cats2.slug AS catslug2
FROM `jos_clothes_products` AS tbl
LEFT JOIN `jos_clothes_brands` AS b ON b.clothes_brand_id = tbl.clothes_brand_id
LEFT JOIN `jos_clothes_resellers` AS r ON r.clothes_reseller_id = tbl.clothes_reseller_id
LEFT JOIN `jos_clothes_catraws` AS rcat ON rcat.clothes_catraw_id = tbl.clothes_catraw_id
LEFT JOIN `jos_clothes_categories` AS cats2 ON cats2.clothes_category_id = rcat.clothes_category_id
LEFT JOIN `jos_clothes_categories` AS cats1 ON cats1.clothes_category_id = cats2.parent_id
然后从PHP运行这样的查询时:
SELECT `tbl`.* FROM `jos_clothes_view_products` AS `tbl` WHERE `tbl`.`cat1` != 'NULL' AND `tbl`.`enabled` = '1' ORDER BY `created_on` DESC , `ordering` ASC LIMIT 0 , 20;
查询通常很慢!并非总是如此(可能是因为缓存?)。我还注意到它创建了一个大约200MB的tmp表。有时候它会变得更大并且因“文件无效密钥......”而失败。
我可以如何优化查询?或者实际上是VIEW,我猜这是瓶颈。正确的吗?
产品表结构:
CREATE TABLE IF NOT EXISTS `jos_clothes_products` (
`clothes_product_id` bigint(20) unsigned NOT NULL auto_increment,
`clothes_reseller_id` bigint(20) unsigned NOT NULL,
`aff_prod_id` varchar(50) NOT NULL,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`gender` varchar(20) NOT NULL,
`clothes_brand_id` bigint(20) unsigned NOT NULL,
`color` varchar(255) NOT NULL,
`size` varchar(50) NOT NULL,
`clothes_catraw_id` bigint(20) unsigned NOT NULL,
`price` decimal(10,2) NOT NULL default '0.00',
`shipping_cost` varchar(20) NOT NULL default '0.00',
`currency` varchar(10) NOT NULL,
`availibility` tinyint(1) NOT NULL,
`product_url` varchar(350) NOT NULL,
`real_url` varchar(300) NOT NULL,
`slug` varchar(255) NOT NULL,
`hits` int(11) NOT NULL,
`enabled` tinyint(1) NOT NULL default '0',
`access` int(11) NOT NULL default '0',
`ordering` bigint(20) unsigned NOT NULL,
`created_on` datetime NOT NULL default '0000-00-00 00:00:00',
`created_by` int(11) NOT NULL default '0',
`modified_on` datetime NOT NULL default '0000-00-00 00:00:00',
`modified_by` int(11) NOT NULL default '0',
`locked_on` datetime NOT NULL default '0000-00-00 00:00:00',
`locked_by` int(11) NOT NULL default '0',
PRIMARY KEY (`clothes_product_id`),
KEY `clothes_brand_id` (`clothes_brand_id`),
KEY `clothes_catraw_id` (`clothes_catraw_id`),
KEY `created_on` (`created_on`),
KEY `clothes_reseller_id` (`clothes_reseller_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18962 ;
有什么想法吗?
最好的问候
编辑:jos_clothes_catraws的结构
--
-- Struktur för tabell `jos_clothes_catraws`
--
CREATE TABLE IF NOT EXISTS `jos_clothes_catraws` (
`clothes_catraw_id` int(11) unsigned NOT NULL auto_increment,
`clothes_category_id` int(11) unsigned NOT NULL default '0',
`clothes_reseller_id` int(11) unsigned NOT NULL,
`raw_name` varchar(255) NOT NULL,
PRIMARY KEY (`clothes_catraw_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1289 ;
答案 0 :(得分:0)
查看您的EXPLAIN输出,看起来罪魁祸首是jos_clothes_catraws
表,它没有使用任何索引来进行连接。这是生成大临时表的那个。首先检查表格是否有clothes_catraw_id
的密钥。
您还可以使用USE INDEX语法强制使用索引或在表上执行ANALYZE TABLE以确保更新表统计信息,以避免临时表。
我能看到的另一点是你在PHP中使用的查询中的升序和降序的混合。尝试对created_on字段使用降序键,最好使用两个字段的组合键。
同时尝试直接运行查询而不是通过视图,因为MySQL Restrictions on Views section中提到某些视图可能不使用索引,尽管实际语句可以使用索引。