优化SQL语句

优化SQL语句,sql,mysql,Sql,Mysql,嘿,我在运行WordPress,数据库图可以在这里找到: 在做了大量的过滤器并对核心应用了一些钩子之后,我只剩下以下查询: SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts JOIN wp_postmeta ppmeta_beds ON (ppmeta_beds.post_id = wp_posts.ID AND ppmeta_beds.meta_key = 'pp-general-beds' AND ppmeta_beds.meta

嘿,我在运行WordPress,数据库图可以在这里找到:

在做了大量的过滤器并对核心应用了一些钩子之后,我只剩下以下查询:

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts 

JOIN wp_postmeta ppmeta_beds ON (ppmeta_beds.post_id = wp_posts.ID AND
  ppmeta_beds.meta_key = 'pp-general-beds' AND ppmeta_beds.meta_value >= 2)

JOIN wp_postmeta ppmeta_baths ON (ppmeta_baths.post_id = wp_posts.ID AND
  ppmeta_baths.meta_key = 'pp-general-baths' AND ppmeta_baths.meta_value >= 3)

JOIN wp_postmeta ppmeta_furnished 
  ON (ppmeta_furnished.post_id = wp_posts.ID AND
  ppmeta_furnished.meta_key = 'pp-general-furnished' 
  AND ppmeta_furnished.meta_value = 'yes')

JOIN wp_postmeta ppmeta_pool 
  ON (ppmeta_pool.post_id = wp_posts.ID AND
  ppmeta_pool.meta_key = 'pp-facilities-pool' 
  AND ppmeta_pool.meta_value = 'yes')

JOIN wp_postmeta ppmeta_pool_type 
  ON (ppmeta_pool_type.post_id = wp_posts.ID AND
  ppmeta_pool_type.meta_key = 'pp-facilities-pool-type' 
  AND ppmeta_pool_type.meta_value 
  IN ('tennis', 'voleyball', 'basketball', 'fitness'))

JOIN wp_postmeta ppmeta_sport ON (ppmeta_sport.post_id = wp_posts.ID AND
  ppmeta_sport.meta_key = 'pp-facilities-sport' 
  AND ppmeta_sport.meta_value = 'yes') 

JOIN wp_postmeta ppmeta_sport_type ON (ppmeta_sport_type.post_id = wp_posts.ID 
  AND ppmeta_sport_type.meta_key = 'pp-facilities-sport-type' 
  AND ppmeta_sport_type.meta_value 
  IN ('tennis', 'voleyball', 'basketball', 'fitness')) 

JOIN wp_postmeta ppmeta_parking ON (ppmeta_parking.post_id = wp_posts.ID 
  AND ppmeta_parking.meta_key = 'pp-facilities-parking' 
  AND ppmeta_parking.meta_value = 'yes') 

JOIN wp_postmeta ppmeta_parking_type 
  ON (ppmeta_parking_type.post_id = wp_posts.ID 
  AND ppmeta_parking_type.meta_key = 'pp-facilities-parking-type' 
  AND ppmeta_parking_type.meta_value IN ('street', 'off-street', 'garage')) 

JOIN wp_postmeta ppmeta_garden ON (ppmeta_garden.post_id = wp_posts.ID 
  AND ppmeta_garden.meta_key = 'pp-facilities-garden' 
  AND ppmeta_garden.meta_value = 'yes') 

JOIN wp_postmeta ppmeta_garden_type 
  ON (ppmeta_garden_type.post_id = wp_posts.ID 
  AND ppmeta_garden_type.meta_key = 'pp-facilities-garden-type' 
  AND ppmeta_garden_type.meta_value IN ('private', 'communal')) 

JOIN wp_postmeta ppmeta_type ON (ppmeta_type.post_id = wp_posts.ID 
  AND ppmeta_type.meta_key = 'pp-general-type' 
  AND ppmeta_type.meta_value IN ('villa', 'apartment', 'penthouse')) 

JOIN wp_postmeta ppmeta_status ON (ppmeta_status.post_id = wp_posts.ID 
  AND ppmeta_status.meta_key = 'pp-general-status' 
  AND ppmeta_status.meta_value IN ('off-plan', 'resale')) 

JOIN wp_postmeta ppmeta_location_type 
  ON (ppmeta_location_type.post_id = wp_posts.ID 
  AND ppmeta_location_type.meta_key = 'pp-location-type' 
  AND ppmeta_location_type.meta_value 
  IN ('beachfront', 'countryside', 'town-center', 'near-the-sea', 
    'hillside', 'private-resort')) 

JOIN wp_postmeta ppmeta_price_range 
  ON (ppmeta_price_range.post_id = wp_posts.ID 
  AND ppmeta_price_range.meta_key = 'pp-general-price' 
  AND ppmeta_price_range.meta_value BETWEEN 10000 AND 50000) 

JOIN wp_postmeta ppmeta_area_range 
  ON (ppmeta_area_range.post_id = wp_posts.ID 
  AND ppmeta_area_range.meta_key = 'pp-general-area' 
  AND ppmeta_area_range.meta_value BETWEEN 50 AND 150) 

WHERE 1=1 AND (((wp_posts.post_title LIKE '%fdsfsad%') 
OR (wp_posts.post_content LIKE '%fdsfsad%'))) 
AND wp_posts.post_type = 'property' 
AND (wp_posts.post_status = 'publish' 
  OR wp_posts.post_status = 'private') 
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
太大了。谁能告诉我一种方法,把所有的连接优化成更少的语句?正如您所看到的,它们都使用相同的表,但名称不同。我不是SQL大师,但我认为应该有办法,因为这太疯狂了

谢谢


这里更新解释返回的内容:

您无法优化它。您需要所有连接,因为它们是独立的过滤器,可能是由于和逻辑,即您需要海滩前面和街道外的停车位


您最好的办法是确保您的表不会出现碎片。有一个关于元值、元键和post-id的索引。

你不能优化它。您需要所有连接,因为它们是独立的过滤器,可能是由于和逻辑,即您需要海滩前面和街道外的停车位


您最好的办法是确保您的表不会出现碎片。有一个关于meta-value、meta-key和post-id的索引。

PHP通过自己的协议连接到mysql。SQL允许的大小增加了MBs,而且由于php/mysql通信在本地主机或局域网上,因此不会成为瓶颈。因此,就php和mysql之间的通信而言,SQL的大小并不重要

在准备SQL解析和规划方面,它可能需要额外的时间,您可以考虑创建一个完成上述操作的视图。 另外,重要的是索引,但是除了文件排序之外,计划看起来还可以——您可能希望有一个索引,可以用于在wp_post上进行排序和选择

此外,您只从WPX POST表中选择列,但正在加入更多的表——考虑在存在条件下重写它。


至于优化,请在数据库中获取一些样本数据,其数量级将模拟最终要使用的数据库的硬件和大小。优化查询是您在开发过程中不应该忘记的事情,但过早花费太多时间可能是不合理的。

PHP通过自己的协议连接到mysql。SQL允许的大小增加了MBs,而且由于php/mysql通信在本地主机或局域网上,因此不会成为瓶颈。因此,就php和mysql之间的通信而言,SQL的大小并不重要

在准备SQL解析和规划方面,它可能需要额外的时间,您可以考虑创建一个完成上述操作的视图。 另外,重要的是索引,但是除了文件排序之外,计划看起来还可以——您可能希望有一个索引,可以用于在wp_post上进行排序和选择

此外,您只从WPX POST表中选择列,但正在加入更多的表——考虑在存在条件下重写它。


至于优化,请在数据库中获取一些样本数据,其数量级将模拟最终要使用的数据库的硬件和大小。优化查询是您在开发过程中不应该忘记的事情,但过早花费太多时间可能是不合理的。

这是一种实现基于属性的搜索的效率特别低的方法。不幸的是,我不知道WordPress是否可以用其他方法实现,即:每个属性都应该有自己的列和索引。这不太灵活,但要快得多。

这是实现基于属性的搜索的一种效率特别低的方法。不幸的是,我不知道WordPress是否可以用其他方法实现,即:每个属性都应该有自己的列和索引。这不太灵活,但要快得多。

正如Simon Sabin已经说过的那样,您无法摆脱连接,因为它们可以作为过滤器工作

出于阅读目的,最好在wp_postETA上有一个索引,如post_id、meta_键、metavalue255。这种顺序很重要,因为按照这种顺序计算联接中的条件,但索引将使数据库的大小加倍,并减慢插入和更新的速度

应用乘积集的条件的顺序也不是最优的:方程应该先去,然后是LIKE和range条件,否则就没有指数用于过滤


最后但并非最不重要的杀手是按post_date排序:由于结果中的每一行都包含文本字段,MySQL将使用文件系统临时表进行排序。如果ID和日期同时增加,则按wp_posts.ID排序可能是一个更好的主意。

正如Simon Sabin已经说过的那样,您无法摆脱连接,因为它们起到过滤器的作用

出于阅读目的,最好在wp_postETA上有一个索引,如post_id、meta_键、metavalue255。这个顺序很重要,因为按照这个顺序计算联接中的条件,但是索引将使数据库的大小加倍,并减慢插入和更新的速度 是的

应用乘积集的条件的顺序也不是最优的:方程应该先去,然后是LIKE和range条件,否则就没有指数用于过滤


最后但并非最不重要的杀手是按post_date排序:由于结果中的每一行都包含文本字段,MySQL将使用文件系统临时表进行排序。如果ID和日期同时增加,则按wp_posts.ID排序可能是一个更好的主意。

你说的“大”是什么意思?文字太多?优化并不是减少文本,而是让它运行得更快。。。它目前运行的速度有多快?你能发布EXPLAIN的输出吗;拜托?jle,我不确定它是如何运行的,因为我没有太多的数据可供实验。我想对它进行优化,以减少PHP和MySQL之间传输的字节。Andy,完成,链接到twitpic。你说的“大”是什么意思?文字太多?优化并不是减少文本,而是让它运行得更快。。。它目前运行的速度有多快?你能发布EXPLAIN的输出吗;拜托?jle,我不确定它是如何运行的,因为我没有太多的数据可供实验。我想对它进行优化,以减少PHP和MySQL之间传输的字节数。Andy,完成,链接到twitpic。我明白了。。还有一个问题。通过php发布这样的查询可以吗?会不会太长?我问的原因是,我的一个朋友在本地主机Windows7上运行了我的脚本,xampp和mysqld进程的CPU占用率高达99%,整个过程都冻结了。在我和我们基于Linux的托管服务上一切都很好。那么这应该被视为配置问题吗?我明白了。。还有一个问题。通过php发布这样的查询可以吗?会不会太长?我问的原因是,我的一个朋友在本地主机Windows7上运行了我的脚本,xampp和mysqld进程的CPU占用率高达99%,整个过程都冻结了。在我和我们基于Linux的托管服务上一切都很好。那么这应该被视为一个配置问题吗?添加一个索引是一个很好的建议-这就是我们在设置中所做的。但是,请注意,联接中条件的顺序与索引中列的顺序无关。MySQL可以对测试索引中所有列的查询使用多列索引,或者只测试第一列、前两列、前三列等的查询。-添加索引的好建议-这是我们在设置中所做的。但是,请注意,联接中条件的顺序与索引中列的顺序无关。MySQL可以对测试索引中所有列的查询使用多个列索引,或者只测试第一列、前两列、前三列等的查询-