提高MySQL查询的速度

时间:2013-02-20 12:34:32

标签: php mysql

编辑:

我按如下方式重新编写了查询:

SELECT
  a.title, count(*),at.search_code
FROM 
  `qitz3_attributes_type` at
left join
  qitz3_attributes a
on 
  a.attribute_type_id = at.id
left join
  qitz3_attributes_property ap
on
  ap.attribute_id = a.id
left join
  qitz3_helloworld h
on
  h.id = ap.property_id
where 
  at.id in (1,2,8,9,11)
and 
  a.search_filter = 1
and
  h.area=506
and 
  h.expiry_date >= '2013-02-20 13:28:04' 
group by 
  a.title
order by search_code

这看起来要快得多,但我仍在使用临时和使用文件解释...

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  at  range   PRIMARY PRIMARY 4   NULL    5   Using where; Using temporary; Using filesort
1   SIMPLE  a   ref PRIMARY,Attribute type ID,Search filter,Attribute ...   Attribute type ID   4   password.at.id  6   Using where
1   SIMPLE  ap  ref Property ID,Attribute ID,Attribute Property Attribute Property  4   password.a.id   142 Using where; Using index
1   SIMPLE  h   eq_ref  PRIMARY,Area indexes,Expiry date    PRIMARY 4   password.ap.property_id 1   Using where

EndEdit中

我正在开发一个我正在开发的网站的搜索组件,虽然它正在运行但有一些查询我希望看到更快地运行触摸。

为了填充一组搜索过滤器(显示具有每个设施或属于特定类型的属性的数量),我使用以下两个查询。第一个将获得一个ID列表,然后插入第二个查询,如下所示:

基于以下信息,任何人都可以建议更有效的方法吗?我真的想加快第一次查询速度,因为与其他查询相比,它似乎有点慢。

150ms实际上是慢吗? 15ms会更好......

谢谢,

亚当

查询1(大约需要150毫秒):

  SELECT h.id, h.parent_id, h.level, h.title as property_title, h.area, h.region, h.department, h.city, 
  LEFT(h.description, 250) as description, h.thumbnail, h.occupancy, h.swimming, g.path, (single_bedrooms + double_bedrooms + triple_bedrooms + quad_bedrooms + twin_bedrooms) as bedrooms, c.title as location_title, ( select min(tariff) 
  from qitz3_tariffs 
  where id = h.id ) as price, e.title as tariff_based_on, f.title as base_currency, a.title as property_type, a2.title as accommodation_type, ( select count(*) 
  from qitz3_reviews 
  where property_id = h.id 
  group by h.id ) as reviews 
  FROM qitz3_classifications c 
  LEFT JOIN qitz3_helloworld h 
  on c.id = h.area 
  LEFT JOIN qitz3_attributes_property ap 
  ON ap.property_id = h.id 
  LEFT JOIN qitz3_attributes_type at 
  ON at.id = ap.attribute_id 
  LEFT JOIN qitz3_attributes a 
  ON a.id = ap.attribute_id 
  LEFT JOIN qitz3_attributes_property ap2 
  ON ap2.property_id = h.id 
  LEFT JOIN qitz3_attributes_type at2 
  ON at2.id = ap2.attribute_id 
  LEFT JOIN qitz3_attributes a2 
  ON a2.id = ap2.attribute_id 
  LEFT JOIN qitz3_attributes e 
  ON e.id = h.tariff_based_on 
  LEFT JOIN qitz3_attributes f 
  ON f.id = h.base_currency 
  LEFT JOIN qitz3_classifications g 
  ON g.id = h.city 
  WHERE a.attribute_type_id = 1 
  AND a2.attribute_type_id = 2 
  AND c.id = 506 
  AND h.expiry_date >= '2013-02-20 12:05:13' 
  AND h.id > 1 

说明:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY c   const   PRIMARY PRIMARY 4   const   1   
1   PRIMARY h   ref PRIMARY,Area indexes,Expiry date    Area indexes    4   const   615 Using where
1   PRIMARY ap  ref Property ID,Attribute ID    Property ID 4   password.h.id   21  Using where
1   PRIMARY at  eq_ref  PRIMARY PRIMARY 4   password.ap.attribute_id    1   Using index
1   PRIMARY a   eq_ref  PRIMARY,Attribute type ID   PRIMARY 4   password.ap.attribute_id    1   Using where
1   PRIMARY ap2 ref Property ID,Attribute ID    Property ID 4   password.ap.property_id 21  Using where
1   PRIMARY at2 eq_ref  PRIMARY PRIMARY 4   password.ap2.attribute_id   1   Using index
1   PRIMARY a2  eq_ref  PRIMARY,Attribute type ID   PRIMARY 4   password.ap2.attribute_id   1   Using where
1   PRIMARY e   eq_ref  PRIMARY PRIMARY 4   password.h.tariff_based_on  1   
1   PRIMARY f   eq_ref  PRIMARY PRIMARY 4   password.h.base_currency    1   
1   PRIMARY g   eq_ref  PRIMARY PRIMARY 4   password.h.city 1   
3   DEPENDENT SUBQUERY  qitz3_reviews   ref Property ID Property ID 4   password.h.id   1   Using index; Using temporary; Using filesort
2   DEPENDENT SUBQUERY  qitz3_tariffs   ref Property ID Property ID 4   password.h.id   2         

查询2(大约需要30ms):

SELECT a.id,count(attribute_id) as count, a.title AS attribute, a.published, at.title as facility_type, at.search_code 
FROM qitz3_attributes AS a 
LEFT JOIN qitz3_attributes_type at 
on at.id = a.attribute_type_id 
LEFT JOIN qitz3_attributes_property ap 
on ap.attribute_id = a.id 
WHERE search_filter = 1 
AND a.published = 1 
AND property_id in (152843,103180,152845,4628,5653,3865,107553,155945,106029,107575,149052,837,104264,98635,98636,98637,98638,3667,106838,3672,157278,155743,157791,157792,151153,151155,100725,106109,157569,157576,107145,150666,103310,5780,3480,102041,154016,3490,154018,932,153518,151991,154041,154042,4288,5832,149451,157646,102094,148444,153822,157407,153839,151536,157393,157395,157428,157429,102236,104770,157378,157380,157381,157382,157383,157654,104768,103746,153683,150175,4618,101050,104942,157229,157230,98515,104771,104944,3612,148721,104212,5307,3432,156676,102706,404,5518,156359,5252,102697,5271,98979,101827,149524,102676,107551,5685,101736,156538,152703,4730,151881,95838,3759,149769,5269,98429,153729,5233,703,5579,98943,157433,3157,155661,107347,147545,147547,5216,106345,156533,93833,158091,96403,3491,968,158195,158196,157580,104148,3030,94686,154725,150582,103027,99062,102462,4384,5634,153874,157974,101669,47,105285,102481,102234,5749,156793,153748,96404,151467,154292,147645,97471,100551,102090,4841,3563,155643,4656,98424,157243,150601,157415,4701,102283,100719,100738,5643,98425,98972,103261,531,3105,98108,150592,5719,150616,157532,3974,3212,157581,97469,97470,149183,157638,149730,102114,156395,153621,102560,102913,94684,5609,157578,98423,98971,102151,146734,150585,104287,155296,104956,94592,102433,147575,156325,106344,101766,107058,106560,103026,157848,98973,4303,5620,149767,150563,4407,104268,97876,156784,156786,149922,701,154317,153821,102480,348,102778,102779,102780,102781,102479,352,103025,98677,5254,98697,3995,156322,100305,98532,3833,5374,150172,151435,102368,102380,157228,103171,147740,152870,103579,3870,104037,103016,4995,105104,157605,5811,955,147643,156648,107802,101502,94685,3569,148755,150293,4122,157013,157297,98676,156794,102848,157635,157640,95717,98980,102764,102777,102782,36,101765,154373,149829,154955,107683,158176,102557,157552,103163,5760,104627,153561,266,151335,151176,147620,147379,3085,155760,106339,151424,106759,5145,104990,97877,155495,5241,156407,156625,3236,152782,96066,147617,3860,4614,3497,147883,158207,102985,104622,101816,157275,149037,4792,149226,3496,101825,102538,150571,105015,97874,157391,158192,102562,155032,5383,102558,104194,156740,101446,147615,5815,107081,155992,97473,148817,945,101751,158074,4249,101792,4532,152828,104316,157319,156071,157508,157510,148836,4745,153823,157942,3859,157442,100017,102555,147629,149272,157845,151256,101481,154735,154737,157652,106232,97991,4660,3309,157597,407,157658,154152,157374,153385,148037,158214,100452)
GROUP BY a.id

此查询提供每个属性的属性数量(例如,高尔夫,空调,属性类型等)。关于这一点的好处是只显示具有属性的属性。因此,当用户向下钻取属性时,不显示任何属性。这基本上是第一个查询,我得到一个匹配特定属性集的属性列表。

表格如下:

-

- 表qitz3_attributes

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_attributes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`attribute_type_id` int(11) NOT NULL,
`title` varchar(75) NOT NULL,
`ordering` int(11) NOT NULL,
`state` tinyint(4) NOT NULL DEFAULT '1',
`published` int(11) NOT NULL,
`search_filter` bit(1) NOT NULL,
`language_code` varchar(6) NOT NULL DEFAULT 'en-GB',
PRIMARY KEY (`id`),
KEY `Attribute type ID` (`attribute_type_id`),
KEY `Search filter` (`search_filter`),
KEY `Published` (`published`)
) ENGINE=InnoDB    DEFAULT CHARSET=latin1 AUTO_INCREMENT=1522 ;

-

- 表qitz3_attributes_property

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_attributes_property` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`property_id` int(11) NOT NULL,
`attribute_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `Property ID` (`property_id`),
KEY `Attribute ID` (`attribute_id`)
) ENGINE=InnoDB    DEFAULT CHARSET=latin1 AUTO_INCREMENT=66261 ;

-

- 表qitz3_attributes_type

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_attributes_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(75) NOT NULL,
`language_code` varchar(6) NOT NULL,
`field_name` varchar(25) NOT NULL,
`search_code` varchar(25) NOT NULL,
`state` int(11) NOT NULL DEFAULT '1',
`published` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB    DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;

-

- 表qitz3_classifications

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_classifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(10) unsigned NOT NULL DEFAULT '0',
`lft` int(11) NOT NULL DEFAULT '0',
`rgt` int(11) NOT NULL DEFAULT '0',
`level` int(10) unsigned NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`path` varchar(255) NOT NULL DEFAULT '',
`alias` varchar(255) NOT NULL,
`access` tinyint(3) unsigned NOT NULL DEFAULT '0',
`published` int(11) NOT NULL,
`longitude` float(10,6) NOT NULL,
`latitude` float(10,6) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_left_right` (`lft`,`rgt`),
KEY `Alias index` (`alias`)
) ENGINE=MyISAM    DEFAULT CHARSET=utf8 AUTO_INCREMENT=158052 ;

-

- 表qitz3_helloworld(属性表)

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_helloworld` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(10) NOT NULL DEFAULT '0',
`lft` int(11) NOT NULL DEFAULT '0',
`rgt` int(11) NOT NULL DEFAULT '0',
`level` int(10) unsigned NOT NULL,
`alias` varchar(250) NOT NULL DEFAULT '',
`access` tinyint(3) unsigned NOT NULL DEFAULT '0',
`path` varchar(255) NOT NULL DEFAULT '',
`title` varchar(120) NOT NULL,
`area` int(11) NOT NULL DEFAULT '0',
`region` int(11) NOT NULL DEFAULT '0',
`department` int(11) NOT NULL DEFAULT '0',
`city` int(11) NOT NULL DEFAULT '0',
`params` text NOT NULL,
`created_by` int(10) NOT NULL DEFAULT '0',
`created_on` datetime NOT NULL,
`modified` datetime DEFAULT NULL,
`expiry_date` date DEFAULT NULL,
`availability_last_updated_on` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL,
`lang` varchar(5) NOT NULL DEFAULT 'en-GB',
`description` mediumtext NOT NULL COMMENT 'The summary and description for this accommodation',
`internal_facilities_other` varchar(1000) NOT NULL,
`external_facilities_other` varchar(1000) NOT NULL,
`activities_other` varchar(5000) NOT NULL,
`location_details` varchar(5000) NOT NULL,
`getting_there` varchar(5000) NOT NULL,
`thumbnail` varchar(150) NOT NULL,
`occupancy` int(11) DEFAULT NULL,
`single_bedrooms` int(11) NOT NULL,
`double_bedrooms` int(11) NOT NULL,
`triple_bedrooms` int(11) DEFAULT NULL,
`quad_bedrooms` int(11) DEFAULT NULL,
`twin_bedrooms` int(11) DEFAULT NULL,
`childrens_beds` int(11) DEFAULT NULL,
`cots` int(11) DEFAULT NULL,
`extra_beds` int(11) DEFAULT NULL,
`bathrooms` int(11) NOT NULL,
`toilets` int(11) DEFAULT NULL,
`swimming` int(11) NOT NULL,
`latitude` decimal(10,7) DEFAULT NULL,
`longitude` decimal(10,7) DEFAULT NULL,
`nearest_town` varchar(50) DEFAULT NULL,
`distance_to_coast` int(11) DEFAULT NULL,
`additional_price_notes` varchar(3000) DEFAULT NULL,
`base_currency` int(11) DEFAULT NULL,
`tariff_based_on` int(11) DEFAULT NULL,
`linen_costs` varchar(250) DEFAULT NULL,
`changeover_day` int(11) DEFAULT NULL,
`published` tinyint(4) NOT NULL DEFAULT '0',
`video` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_left_right` (`lft`,`rgt`),
KEY `Area indexes` (`area`,`region`,`department`),
KEY `Expiry date` (`expiry_date`)
) ENGINE=InnoDB    DEFAULT CHARSET=utf8 AUTO_INCREMENT=158249 ;

-

- 表qitz3_reviews

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_reviews` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`property_id` int(11) NOT NULL,
`title` varchar(150) NOT NULL,
`review_text` varchar(4000) NOT NULL,
`date` date NOT NULL,
`rating` int(11) NOT NULL,
`guest_name` varchar(75) NOT NULL,
`guest_email` varchar(150) NOT NULL,
`state` tinyint(3) NOT NULL DEFAULT '0',
`published` tinyint(1) NOT NULL DEFAULT '0',
`created` datetime NOT NULL,
`created_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `Property ID` (`property_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=921 ;

-

- 表qitz3_tariffs

的表结构
CREATE TABLE IF NOT EXISTS `qitz3_tariffs` (
`tariff_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) NOT NULL COMMENT 'Denotes the property listing ID',
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`tariff` int(11) NOT NULL COMMENT 'Price per booking period between the dates specified. dated spec',
PRIMARY KEY (`tariff_id`),
KEY `Property ID` (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9267 ;

3 个答案:

答案 0 :(得分:1)

快速播放,但尝试从字段列表中移出子选择。

SELECT h.id, h.parent_id, h.level, h.title as property_title, h.area, h.region, h.department, h.city, LEFT(h.description, 250) as description, h.thumbnail, h.occupancy, h.swimming, g.path, (single_bedrooms + double_bedrooms + triple_bedrooms + quad_bedrooms + twin_bedrooms) as bedrooms, c.title as location_title, 
Sub1.price, 
e.title as tariff_based_on, f.title as base_currency, a.title as property_type, a2.title as accommodation_type, 
Sub2.reviews 
FROM qitz3_classifications c 
LEFT JOIN qitz3_helloworld h on c.id = h.area 
LEFT JOIN qitz3_attributes_property ap ON ap.property_id = h.id 
LEFT JOIN qitz3_attributes_type at ON at.id = ap.attribute_id 
LEFT JOIN qitz3_attributes a ON a.id = ap.attribute_id 
LEFT JOIN qitz3_attributes_property ap2 ON ap2.property_id = h.id 
LEFT JOIN qitz3_attributes_type at2 ON at2.id = ap2.attribute_id 
LEFT JOIN qitz3_attributes a2 ON a2.id = ap2.attribute_id 
LEFT JOIN qitz3_attributes e ON e.id = h.tariff_based_on 
LEFT JOIN qitz3_attributes f ON f.id = h.base_currency 
LEFT JOIN qitz3_classifications g ON g.id = h.city 
LEFT JOIN ( SELECT id, MIN(tariff) AS price FROM qitz3_tariffs GROUP BY id) Sub1 ON Sub1.Id = h.id 
LEFT JOIN ( SELECT property_id, COUNT(*) AS reviews FROM qitz3_reviews GROUP BY property_id ) as Sub2 ON Sub2.property_id = h.id 
WHERE a.attribute_type_id = 1 
AND a2.attribute_type_id = 2 
AND c.id = 506 
AND h.expiry_date >= '2013-02-20 12:05:13' 
AND h.id > 1 

答案 1 :(得分:0)

如果您需要更快的搜索数据,请查看SolrSphinx。使用此索引服务器,您可以索引MySQL数据并查询它们。

它比MySQL快得多。

答案 2 :(得分:0)

您的第一个查询中存在很多错误:

前7个LEFT JOIN应为INNER JOIN。对于qitz3_attributes,您应该考虑较不积极地规范化数据(使用多列而不是多行来描述数据。