优化地理搜索查询

时间:2017-02-01 09:22:47

标签: mysql database performance mariadb

我目前正在user_geo_places表中存储用户位置。 我存储了他们所有的最新位置,包括过去的位置。

我需要的常见任务,

  • 仅按类别查询最新位置
  • 在指定位置查询附近的用户
  • 按距离订购结果
  • 根据指定的位置获取每个结果基础的距离

表格

+------------+---------------+------+-----+---------------------+-------+
| Field      | Type          | Null | Key | Default             | Extra |
+------------+---------------+------+-----+---------------------+-------+
| id         | varchar(36)   | NO   |     | NULL                |       |
| user_id    | varchar(36)   | NO   | MUL | NULL                |       |
| deleted_at | timestamp     | YES  |     | NULL                |       |
| created_at | timestamp     | NO   |     | 0000-00-00 00:00:00 |       |
| updated_at | timestamp     | NO   | MUL | 0000-00-00 00:00:00 |       |
| latitude   | double(25,20) | NO   | MUL | NULL                |       |
| longitude  | double(25,20) | NO   | MUL | NULL                |       |
| category   | varchar(36)   | YES  |     | NULL                |       |
| status     | int(11)       | YES  |     | 1                   |       |
+------------+---------------+------+-----+---------------------+-------+

这是我的索引

+-----------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table           | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user_geo_places |          1 | latitude   |            1 | latitude    | A         |     1894347 |     NULL | NULL   |      | BTREE      |         |               |
| user_geo_places |          1 | longitude  |            1 | longitude   | A         |     1894347 |     NULL | NULL   |      | BTREE      |         |               |
| user_geo_places |          1 | updated_at |            1 | updated_at  | A         |          18 |     NULL | NULL   |      | BTREE      |         |               |
| user_geo_places |          1 | user_id    |            1 | user_id     | A         |     1894347 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

获取每个用户的最新位置

Select  user_geo_places.*
    from  user_geo_places
    left join  user_geo_places b
               ON (user_geo_places.user_id = b.user_id
              and  user_geo_places.created_at < b.created_at )
    where  b.created_at is NULL
      and  user_geo_places.category = 'plcs'

结果:

+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+--------------------------+----------+---------+
| id                                   | user_id                              | deleted_at | created_at          | updated_at          | latitude                | longitude                | category | status  |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+--------------------------+----------+---------+
| 00019a37-e790-11e6-8469-5404a66ff99a | e20e7777-e788-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.48057242434525200000 | -74.44768883329601000000 | plcs     |       1 |
| 0006162a-e790-11e6-8469-5404a66ff99a | e20e7aef-e772-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.79672692417793640000 | -74.64056815173530000000 | plcs     |       1 |
| 000617f7-e790-11e6-8469-5404a66ff99a | e20ec3c5-e775-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.81266001687632900000 | -74.14159565990940000000 | plcs     |       1 |
| 00061914-e790-11e6-8469-5404a66ff99a | e20edec3-e785-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.26999827965162600000 | -74.92520444926359000000 | plcs     |       1 |
| 00061a1d-e790-11e6-8469-5404a66ff99a | e20eefec-e780-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.81602743809672800000 | -74.30452387342650000000 | plcs     |       1 |
| 00061b21-e790-11e6-8469-5404a66ff99a | e20f3219-e766-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.07453708357600200000 | -74.45911382833413000000 | plcs     |       1 |
| 00061c1e-e790-11e6-8469-5404a66ff99a | e20f7922-e786-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.07195792167629800000 | -74.98244815411275000000 | plcs     |       1 |
| 00061d0e-e790-11e6-8469-5404a66ff99a | e20fd68b-e77e-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.69636703626845700000 | -74.53449074973770000000 | plcs     |       1 |
| 00061e01-e790-11e6-8469-5404a66ff99a | e20fe033-e76b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.58335267061679900000 | -74.31329113460453000000 | plcs     |       1 |
| 00061ef4-e790-11e6-8469-5404a66ff99a | e2101c1b-e776-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.81639769190586900000 | -74.14211508644942000000 | plcs     |       1 |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+--------------------------+----------+---------+
10 rows in set (0.00 sec)

解释

+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-------------------------+
| id   | select_type | table           | type | possible_keys | key     | key_len | ref                                 | rows    | Extra                   |
+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-------------------------+
|    1 | SIMPLE      | user_geo_places | ALL  | NULL          | NULL    | NULL    | NULL                                | 1894347 | Using where             |
|    1 | SIMPLE      | b               | ref  | user_id       | user_id | 110     | user_geo_places.user_id             |       1 | Using where; Not exists |
+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-------------------------+
2 rows in set (0.00 sec)

现在,当我想让用户按距离定位时

Select  user_geo_places.*, (6371 * acos(cos(radians(40.3987545691419)) *
              cos(radians(user_geo_places.latitude)) *
              cos(radians(user_geo_places.longitude)-
              radians(-74.70559604904))+sin(radians(40.3987545691419)) *
              sin(radians(user_geo_places.latitude)))) as distance
    from  user_geo_places
    left join  user_geo_places b
               ON (user_geo_places.user_id = b.user_id
              and  user_geo_places.created_at < b.created_at )
    where  b.created_at is NULL
      and  user_geo_places.category = 'plcs'
    having  distance <= 10
    order by  distance
    limit  10;

结果:

+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+---------------------------+----------+---------+---------------------+
| id                                   | user_id                              | deleted_at | created_at          | updated_at          | latitude                | longitude                 | category | status  | distance            |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+---------------------------+----------+---------+---------------------+
| c4d8e37b-e78f-11e6-8469-5404a66ff99a | 52616262-e78d-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39875468090060600000 | -74.70637827898038000000 | plcs     |       1 | 0.08625581062811027 |
| f4457454-e78f-11e6-8469-5404a66ff99a | cff6b247-e76e-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39847620893127900000 | -74.70646391688517000000 | plcs     |       1 | 0.10058008395499662 |
| bc0dbef2-e78f-11e6-8469-5404a66ff99a | 29ea9f29-e76a-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39796618688662200000 | -74.70656721545996000000 | plcs     |       1 | 0.13839511964323015 |
| c5949373-e78f-11e6-8469-5404a66ff99a | 53e7b25c-e778-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39938782472106400000 | -74.70438668849356000000 | plcs     |       1 | 0.15080387665201841 |
| c9771f58-e78f-11e6-8469-5404a66ff99a | 647afd7e-e76b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40025693587982800000 | -74.70498255799058000000 | plcs     |       1 | 0.18023303176011723 |
| d1d0d5fe-e78f-11e6-8469-5404a66ff99a | 83e6d50e-e78c-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39976791050263500000 | -74.70698894253651000000 | plcs     |       1 | 0.19049204594530353 |
| c8592196-e78f-11e6-8469-5404a66ff99a | 5ef475ae-e789-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39691713303040500000 | -74.70603059763650000000 | plcs     |       1 | 0.20985736972660576 |
| b855003d-e78f-11e6-8469-5404a66ff99a | 18f63baa-e766-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40058719124699700000 | -74.70495101688891000000 | plcs     |       1 | 0.21583472659797534 |
| 0247ffb0-e790-11e6-8469-5404a66ff99a | e534712d-e77b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40040703062006000000 | -74.70668734489631000000 | plcs     |       1 | 0.21964310635910547 |
| ef647fab-e78f-11e6-8469-5404a66ff99a | c981f563-e765-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40036358721588200000 | -74.70425795922452000000 | plcs     |       1 |  0.2319081044464142 |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+-------------------------+--------------------------+----------+---------+---------------------+
10 rows in set (14.90 sec)

该死。 15秒?这对网络查询来说非常慢。

解释

+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-----------------------------+
| id   | select_type | table           | type | possible_keys | key     | key_len | ref                                 | rows    | Extra                       |
+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-----------------------------+
|    1 | SIMPLE      | user_geo_places | ALL  | NULL          | NULL    | NULL    | NULL                                | 1894347 | Using where; Using filesort |
|    1 | SIMPLE      | b               | ref  | user_id       | user_id | 110     | user_geo_places.user_id             |       1 | Using where; Not exists     |
+------+-------------+-----------------+------+---------------+---------+---------+-------------------------------------+---------+-----------------------------+
2 rows in set (0.00 sec)

我不想扫描整个数据库。我只需要10公里附近的用户。

Select  user_geo_places.*, (6371 * acos(cos(radians(40.3987545691419)) *
         cos(radians(user_geo_places.latitude)) *
         cos(radians(user_geo_places.longitude)-
         radians(-74.70559604904))+sin(radians(40.3987545691419)) *
         sin(radians(user_geo_places.latitude)))) as distance
    from  user_geo_places
    left join  user_geo_places b  ON (user_geo_places.user_id = b.user_id
              and  user_geo_places.created_at < b.created_at
                          )
    where  b.created_at is NULL
      and  user_geo_places.category = 'plcs'
      and  user_geo_places.longitude
         between -74.70559604904 - 10 / abs(cos(radians( 40.3987545691419 )) * 111.045)
             AND -74.70559604904 + 10 / abs(cos(radians( 40.3987545691419 )) * 111.045)
      and  user_geo_places.latitude
         between 40.3987545691419 - ( 10 / 111.045 )
             AND 40.3987545691419 + ( 10 / 111.045 )
    having  distance <= 10
    order by  distance
    limit  10;

结果:

+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
| id                                   | user_id                              | deleted_at | created_at          | updated_at          | latitude               | longitude                | category | status  | distance            |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
| c4d8e37b-e78f-11e6-8469-5404a66ff99a | 52616262-e78d-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39875468090060600000 | -74.70637827898038000000 | plcs     |       1 | 0.08625581062811027 |
| f4457454-e78f-11e6-8469-5404a66ff99a | cff6b247-e76e-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39847620893127900000 | -74.70646391688517000000 | plcs     |       1 | 0.10058008395499662 |
| bc0dbef2-e78f-11e6-8469-5404a66ff99a | 29ea9f29-e76a-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39796618688662200000 | -74.70656721545996000000 | plcs     |       1 | 0.13839511964323015 |
| c5949373-e78f-11e6-8469-5404a66ff99a | 53e7b25c-e778-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39938782472106400000 | -74.70438668849356000000 | plcs     |       1 | 0.15080387665201841 |
| c9771f58-e78f-11e6-8469-5404a66ff99a | 647afd7e-e76b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40025693587982800000 | -74.70498255799058000000 | plcs     |       1 | 0.18023303176011723 |
| d1d0d5fe-e78f-11e6-8469-5404a66ff99a | 83e6d50e-e78c-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39976791050263500000 | -74.70698894253651000000 | plcs     |       1 | 0.19049204594530353 |
| c8592196-e78f-11e6-8469-5404a66ff99a | 5ef475ae-e789-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39691713303040500000 | -74.70603059763650000000 | plcs     |       1 | 0.20985736972660576 |
| b855003d-e78f-11e6-8469-5404a66ff99a | 18f63baa-e766-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40058719124699700000 | -74.70495101688891000000 | plcs     |       1 | 0.21583472659797534 |
| 0247ffb0-e790-11e6-8469-5404a66ff99a | e534712d-e77b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40040703062006000000 | -74.70668734489631000000 | plcs     |       1 | 0.21964310635910547 |
| ef647fab-e78f-11e6-8469-5404a66ff99a | c981f563-e765-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40036358721588200000 | -74.70425795922452000000 | plcs     |       1 |  0.2319081044464142 |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
10 rows in set (2 min 53.63 sec)

哦,来吧。真? 2分钟和53.63秒?那太可怕了。

解释:

+------+-------------+-----------------+-------+--------------------+----------+---------+-------------------------------------+--------+----------------------------------------------------+
| id   | select_type | table           | type  | possible_keys      | key      | key_len | ref                                 | rows   | Extra                                              |
+------+-------------+-----------------+-------+--------------------+----------+---------+-------------------------------------+--------+----------------------------------------------------+
|    1 | SIMPLE      | user_geo_places | range | latitude,longitude | latitude | 8       | NULL                                | 683684 | Using index condition; Using where; Using filesort |
|    1 | SIMPLE      | b               | ref   | user_id            | user_id  | 110     | user_geo_places.user_id             |      1 | Using where; Not exists                            |
+------+-------------+-----------------+-------+--------------------+----------+---------+-------------------------------------+--------+----------------------------------------------------+
2 rows in set (0.01 sec)

也许是因为计算结果。让我们移动一些并设置为 变量

Set @lon1= -74.70559604904 - 10 / abs(cos(radians( 40.3987545691419 )) * 111.045) ;
Set @lon2= -74.70559604904 + 10 / abs(cos(radians( 40.3987545691419 )) * 111.045) ;
Set @lat1= 40.3987545691419 - ( 10 / 111.045 );
Set @lat2= 40.3987545691419 + ( 10 / 111.045 );
Select
user_geo_places.*,
(6371 * acos(cos(radians(40.3987545691419)) * cos(radians(user_geo_places.latitude)) * cos(radians(user_geo_places.longitude)-radians(-74.70559604904))+sin(radians(40.3987545691419)) * sin(radians(user_geo_places.latitude)))) as distance
from user_geo_places
left join user_geo_places b
on (user_geo_places.user_id = b.user_id and user_geo_places.created_at < b.created_at)
    where  b.created_at is NULL
      and  user_geo_places.category = 'plcs'
      and  user_geo_places.longitude between @lon1 AND @lon2
      and  user_geo_places.latitude  between @lat1 AND @lat2
    having  distance <= 10
    order by  distance
    limit  10;

结果:

+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
| id                                   | user_id                              | deleted_at | created_at          | updated_at          | latitude               | longitude                | category | status  | distance            |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
| c4d8e37b-e78f-11e6-8469-5404a66ff99a | 52616262-e78d-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39875468090060600000 | -74.70637827898038000000 | plcs     |       1 | 0.08625581062811027 |
| f4457454-e78f-11e6-8469-5404a66ff99a | cff6b247-e76e-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39847620893127900000 | -74.70646391688517000000 | plcs     |       1 | 0.10058008395499662 |
| bc0dbef2-e78f-11e6-8469-5404a66ff99a | 29ea9f29-e76a-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39796618688662200000 | -74.70656721545996000000 | plcs     |       1 | 0.13839511964323015 |
| c5949373-e78f-11e6-8469-5404a66ff99a | 53e7b25c-e778-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39938782472106400000 | -74.70438668849356000000 | plcs     |       1 | 0.15080387665201841 |
| c9771f58-e78f-11e6-8469-5404a66ff99a | 647afd7e-e76b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40025693587982800000 | -74.70498255799058000000 | plcs     |       1 | 0.18023303176011723 |
| d1d0d5fe-e78f-11e6-8469-5404a66ff99a | 83e6d50e-e78c-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39976791050263500000 | -74.70698894253651000000 | plcs     |       1 | 0.19049204594530353 |
| c8592196-e78f-11e6-8469-5404a66ff99a | 5ef475ae-e789-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.39691713303040500000 | -74.70603059763650000000 | plcs     |       1 | 0.20985736972660576 |
| b855003d-e78f-11e6-8469-5404a66ff99a | 18f63baa-e766-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40058719124699700000 | -74.70495101688891000000 | plcs     |       1 | 0.21583472659797534 |
| 0247ffb0-e790-11e6-8469-5404a66ff99a | e534712d-e77b-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40040703062006000000 | -74.70668734489631000000 | plcs     |       1 | 0.21964310635910547 |
| ef647fab-e78f-11e6-8469-5404a66ff99a | c981f563-e765-11e6-8469-5404a66ff99a | NULL       | 2017-01-31 16:31:48 | 2017-01-31 16:31:48 | 40.40036358721588200000 | -74.70425795922452000000 | plcs     |       1 |  0.2319081044464142 |
+--------------------------------------+--------------------------------------+------------+---------------------+---------------------+------------------------+--------------------------+----------+---------+---------------------+
10 rows in set (2 min 56.29 sec)

曼。你真的很慢我不知道该怎么办你了。是时候向专家们询问了这一点。

目前。我的表中存有180万个虚拟数据。我的查询仍然很慢。此表按类别存储位置,因此此位置还有其他类别。有什么好方法可以修复和改进吗?

如果我无法解决这个问题。我打算按表格按类别移动所有数据。如果由于他们过去的locatins,事情仍然会变慢。我可能会删除该功能,但我真的想实现这一目标。希望有人能帮助我

编辑1:

Show Create Table :

+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table           | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user_geo_places | CREATE TABLE `user_geo_places` (
  `id` varchar(36) NOT NULL,
  `user_id` varchar(36) NOT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `latitude` double(25,20) NOT NULL,
  `longitude` double(25,20) NOT NULL,
  `category` varchar(36) DEFAULT NULL,
  `status` int(11) DEFAULT '1',
  KEY `latitude` (`latitude`),
  KEY `longitude` (`longitude`),
  KEY `updated_at` (`updated_at`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+



+--------------------------------+----------------------+
| Variable_name                  | Value                |
+--------------------------------+----------------------+
| aria_pagecache_age_threshold   | 300                  |
| aria_pagecache_buffer_size     | 134217728            |
| aria_pagecache_division_limit  | 100                  |
| aria_pagecache_file_hash_size  | 512                  |
| binlog_cache_size              | 32768                |
| binlog_stmt_cache_size         | 32768                |
| have_query_cache               | YES                  |
| host_cache_size                | 279                  |
| innodb_disable_sort_file_cache | OFF                  |
| innodb_ft_cache_size           | 8000000              |
| innodb_ft_result_cache_limit   | 2000000000           |
| innodb_ft_total_cache_size     | 640000000            |
| join_cache_level               | 2                    |
| key_cache_age_threshold        | 300                  |
| key_cache_block_size           | 1024                 |
| key_cache_division_limit       | 100                  |
| key_cache_file_hash_size       | 512                  |
| key_cache_segments             | 0                    |
| max_binlog_cache_size          | 18446744073709547520 |
| max_binlog_stmt_cache_size     | 18446744073709547520 |
| metadata_locks_cache_size      | 1024                 |
| query_cache_limit              | 1048576              |
| query_cache_min_res_unit       | 4096                 |
| query_cache_size               | 1048576              |
| query_cache_strip_comments     | OFF                  |
| query_cache_type               | OFF                  |
| query_cache_wlock_invalidate   | OFF                  |
| stored_program_cache           | 256                  |
| table_definition_cache         | 400                  |
| table_open_cache               | 431                  |
| thread_cache_size              | 0                    |
+--------------------------------+----------------------+

服务器规格

  • 4核

  • 8 gb ram

  • MariaDB 10.1.20

使用的引擎:InnoDB

总行数:1,894,326

innodb_buffer_pool_size:134,217,728

目前98%的记录都在纽约

运行SQL_NO_CACHE

Select SQL_NO_CACHE
    user_geo_places.*
from user_geo_places
left join user_geo_places b
on (user_geo_places.user_id = b.user_id and user_geo_places.created_at < b.created_at)
where b.created_at is NULL and user_geo_places.category = 'plcs'
limit 10

10 rows in set (0.00 - 0.07 sec)

顺便说一下,列状态是无用的,将会丢弃

1 个答案:

答案 0 :(得分:0)

缩小表格可以帮助一些

  • double(25,20)需要12个字节,并且在分子宽度附近有一个精度。
  • UUIDs可以打包到BINARY(16)(16个字节)而不是VARCHAR(36)(37个字节)。
  • category规范化为2字节SMALLINT UNSIGNED可能很有用。
  • INT总是4个字节;对TINYINT
  • 等标记使用1字节status

如果没有SHOW CREATE TABLE,我们就看不到索引,尤其是您是否有单列索引或复合索引。

  • 按类别划分的最新内容可能会受益于INDEX(category, created_at)
  • '附近'和'按距离排序'特别困难;见here

将“当前状态”和“历史”分成两个表通常很有用。前者每个实体只有一行;后者(可能)有很多。这极大地简化了涉及“最新”的查询。这也可以让你通过从“当前状态”中删除死条目而将其留在“历史记录”中来摆脱status。过滤status 可能(目前)是查询中的另一个性能杀手。

看起来UUIDs是“类型1”;除了缩小它们之外,它们的位可以重新排列,使它们按时间顺序排列。他们将通过改进“引用的局部性”来提高某些查询的性能。请参阅here

桌子使用什么引擎?该引擎的缓存有多大?你有多少RAM?

LEFT JOIN需要INDEX(user_id, created_at)。 (当然,如果你将历史记录分开,这将不再具有相关性。)

该表的百分之几是“当前状态”?

我提出了几点建议;很难说哪种方式最有益。

为什么使用边界框运行这么慢?它似乎是一个组合的东西:

  • 纽约市20公里,占地面积很大。也许是表的1/3 ??
  • 在决定使用索引和简单扫描表格时,优化程序并不总是“正确”。后者会更快这个时间。
  • 可能是一些缓存问题。