2017-02-01 10 views
2

В настоящее время я сохраняю местоположение пользователя в таблице user_geo_places. Я храню все их последнее местоположение, включая их прошлые местоположения.Оптимизация запроса геоинформации

Общие задачи мне нужно,

  • запрос только Lastest расположение категории
  • запросов поблизости пользователей на месте, указанном
  • результат по расстоянию
  • прибудете расстояние для каждого результата базы на месте, указанном

Таблица

+------------+---------------+------+-----+---------------------+-------+ 
| 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) 

Человек. вы действительно медленны. Я не знаю, что с тобой делать. время, чтобы спросить экспертов об этом.

В настоящее время. У меня 1.8 миллионов фиктивных данных, хранящихся в моей таблице. Мой запрос все еще очень медленный. В этой таблице хранятся местоположения по категориям, поэтому для этого местоположения существуют другие категории. Любой хороший способ исправить и улучшить это?

Если я не могу это исправить. Я планирую переместить все данные по категориям за стол. Если все будет по-прежнему медленнее из-за их прошлых локаций. Я мог бы удалить эту функцию, но я действительно хотел добиться этого. надеюсь, что кто-то может помочь мне

Edit 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 Гб оперативной памяти

  • MariaDB 10.1.20

двигателя используется: InnoDB

Общее количество строк: 1894326

innodb_buffer_pool_size: 134217728

В настоящее время 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) 

У wa y, состояние колонки бесполезно и будет уменьшаться

+0

Какая у вас версия mysql? –

+0

Сколько строк в таблицах? –

+0

[_UUIDs_] (https://mariadb.com/kb/en/guiduuid-performance/) и [_lat/lng_] (https://mariadb.com/kb/en/latitudelongitude-indexing/) трудно оптимизировать , Прочтите эти ссылки, чтобы узнать, помогут ли некоторые из советов. Тогда, я буду рассматривать копать глубже. –

ответ

0

Сокращение стола поможет .

  • double(25,20) занимает 12 байт и имеет точность где-то вокруг ширины молекул.
  • UUIDs может быть упакован в BINARY(16) (16 байт) вместо VARCHAR(36) (37 байт).
  • Возможно, было бы полезно нормализовать category в 2-байтовый SMALLINT UNSIGNED.
  • INT всегда 4 байта; используйте 1-байтовый TINYINT для таких флагов, как status.

Без SHOW CREATE TABLE мы не можем видеть индексы, особенно если у вас есть индексы с одним столбцом или составные индексы.

  • Последние категории могли бы извлечь выгоду из INDEX(category, created_at)
  • «Рядом» и «порядок на расстоянии» особенно трудно; см. here.

Часто полезно разделять «текущее состояние» и «историю» на две таблицы. Первая имеет только одну строку на сущность; последний имеет (потенциально) много. Это значительно упрощает запросы с участием «последних». Это также может позволить вам избавиться от status, удалив мертвую запись из «текущего состояния», оставив ее в «истории».Фильтрация на statusможет (в настоящее время) быть еще одним убийцей производительности в запросах.

Похоже, что UUIDs являются «типом 1»; в дополнение к их сокращению их биты могут быть перегруппированы, чтобы сделать их хронологически упорядоченными. Они улучшат производительность примерно запросов, улучшив «местность ссылки». См. here.

Какой двигатель использует таблица? Насколько велик кеш для этого движка? Сколько у вас RAM?

LEFT JOININDEX(user_id, created_at). (Конечно, если вы отделите историю, это больше не будет актуальным.)

Какой процент таблицы является «текущим состоянием»?

Я представил несколько предложений; трудно сказать, какая из них будет самой выгодной.

Почему работа с ограничительной рамкой работала так медленно? Кажется, что это комбинация вещей:

  • 20km в NYC покрывает много территории. И, возможно, 1/3 стола?
  • Оптимизатор не всегда «поправляется» при решении вопроса об использовании индекса и просто сканировании таблицы. Последний был бы быстрее это раз.
  • Возможно, некоторые проблемы с кешированием.
+0

Привет, Рик, Спасибо за ваше время. Я обновил свой вопрос. похоже, у меня много ошибок. Я хранил местоположение каждого блоха у собаки, я изменю его на DECIMAL (6,4) и будет использовать автоматическое приращение для id. – 3RDIE

+0

Кстати. как определить, есть ли какие-либо проблемы с кешированием? – 3RDIE

+0

Cache ... Сколько оперативной памяти, какой движок, насколько велика таблица, является кешем запросов? –

Смежные вопросы