Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 优化复杂的SQL查询_Php_Mysql_Sql_Symfony_Doctrine - Fatal编程技术网

Php 优化复杂的SQL查询

Php 优化复杂的SQL查询,php,mysql,sql,symfony,doctrine,Php,Mysql,Sql,Symfony,Doctrine,我在我的Symfony2站点上使用了以下查询,用于定位距离地图上给定点最近的纬度和经度对。有一个表“latlong”存储这些对,还有一个表“fos_user_user”存储用户,还有一个“usermeta”表存储关于这些用户的数据(这是我们从wordpress移动所有数据时的遗留问题)。问题是它运行得非常慢——当我们在旧的WordPress站点上运行一个非常简单的查询时,它通常相当快。有人知道如何优化它吗 SELECT latlong.user AS id, fos_user_use

我在我的Symfony2站点上使用了以下查询,用于定位距离地图上给定点最近的纬度和经度对。有一个表“latlong”存储这些对,还有一个表“fos_user_user”存储用户,还有一个“usermeta”表存储关于这些用户的数据(这是我们从wordpress移动所有数据时的遗留问题)。问题是它运行得非常慢——当我们在旧的WordPress站点上运行一个非常简单的查询时,它通常相当快。有人知道如何优化它吗

SELECT 
  latlong.user AS id, 
  fos_user_user.username AS username, 
  latlong.lat AS lat, 
  latlong.lng AS lng, 
  fos_user_user.email_canonical AS email, 
  firstname.VALUE AS firstname, 
  lastname.VALUE AS lastname, 
  address1.VALUE AS address1, 
  address2.VALUE AS address2, 
  address3.VALUE AS address3, 
  postcode.VALUE AS postcode, 
  image.VALUE AS image, 
  (
    3959 * ACOS(
      COS(
        RADIANS('51.4424728')
      ) * COS(
        RADIANS(lat)
      ) * COS(
        RADIANS(lng) - RADIANS('7.2586558')
      ) + SIN(
        RADIANS('51.4424728')
      ) * SIN(
        RADIANS(lat)
      )
    )
  ) AS distance 
FROM 
  latlong 
  JOIN fos_user_user ON latlong.user = fos_user_user.id 
  LEFT JOIN usermeta AS firstname ON firstname.user_id = latlong.user 
  AND firstname.field_id = '15' 
  LEFT JOIN usermeta AS lastname ON lastname.user_id = latlong.user 
  AND lastname.field_id = '16' 
  LEFT JOIN usermeta AS image ON image.user_id = latlong.user 
  AND image.field_id = '11' 
  LEFT JOIN usermeta AS address1 ON address1.user_id = latlong.user 
  AND address1.field_id = '2' 
  LEFT JOIN usermeta AS address2 ON address1.user_id = latlong.user 
  AND address1.field_id = '3' 
  LEFT JOIN usermeta AS address3 ON address1.user_id = latlong.user 
  AND address1.field_id = '4' 
  LEFT JOIN usermeta AS postcode ON postcode.user_id = latlong.user 
  AND postcode.field_id = '5' 
  LEFT JOIN usermeta AS public ON public.user_id = latlong.user 
  AND public.field_id = '10' 
WHERE 
  public.value = 'YES' 
HAVING 
  distance < 25 
ORDER BY 
  distance ASC 
LIMIT 
  0, 5
选择
latlong.user作为id,
fos_user_user.username作为用户名,
latlong.lat作为lat,
latlong.lng作为液化天然气,
fos_user_user.email_标准电子邮件,
firstname.VALUE作为firstname,
lastname.VALUE作为lastname,
address1.VALUE作为address1,
address2.VALUE作为address2,
address3.VALUE作为address3,
postcode.VALUE作为邮政编码,
图像。作为图像的值,
(
3959*ACOS(
因为(
弧度('51.4424728')
)*COS(
弧度(纬度)
)*COS(
弧度(lng)-弧度('7.2586558')
)+罪(
弧度('51.4424728')
)*罪(
弧度(纬度)
)
)
)作为距离
从…起
拉特朗
在latlong.user=fos\u user\u user.id上加入fos\u user\u user
在firstname.user\u id=latlong.user上将usermeta作为firstname左连接
firstname.field_id='15'
在lastname.user\u id=latlong.user上将usermeta作为lastname左连接
lastname.field_id='16'
在image.user\u id=latlong.user上将usermeta作为图像左连接
和image.field_id='11'
在address1.user\u id=latlong.user上将usermeta作为address1左连接
和地址1.field_id='2'
在address1.user\u id=latlong.user上将usermeta作为address2左连接
地址1.field_id='3'
在address1.user\u id=latlong.user上将usermeta作为address3左连接
地址1.field_id='4'
在postcode.user\u id=latlong.user上将usermeta作为邮政编码左连接
和postcode.field_id='5'
在public.user\u id=latlong.user上将usermeta作为public左连接
和public.field_id='10'
哪里
public.value='YES'
有
距离<25
订购人
距离ASC
限度
0, 5

表格结构<代码>解释?糟糕的数据库设计。您知道public.value='YES'使最后一个左连接作为内部连接执行的位置吗?(将条件移动到ON子句以作为左连接执行。)通常对于聚合函数,将该条件移动到WHERE。(MySQL扩展以允许列在那里…)您需要更强大的功能。在这种情况下,mysql必须计算到所有用户的距离(所有这些连接)。感谢您的评论,共有3个表涉及fos_user_user(用户表)、usermeta(包含3列的meta values表、user_id、field_id和value-基本上是EAV中的values表),latlong-这有纬度和经度对,还有一个用户ID@jarlh-你能举个例子说明如何将public.value=10条件与ON子句结合起来吗?