簡體   English   中英

MySQL查詢性能調優

[英]MySQL query performance tuning

我正在嘗試對具有約100萬條記錄的表進行查詢。 該表及其索引的結構為:

CREATE TABLE `table` (
    `Id` int(11) NOT NULL,
    `Name` varchar(510) DEFAULT NULL,
    `Latitude` float NOT NULL DEFAULT '0',
    `Longitude` float NOT NULL DEFAULT '0',
    PRIMARY KEY (`Latitude`,`Longitude`,`Id`),
    KEY `IX_Latitude_Longitude` (`Latitude`,`Longitude`),
    KEY `IX_Latitude` (`Latitude`),
    KEY `IX_Longitude` (`Longitude`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我正在運行以下查詢:

SELECT m.Id, m.Name, sqrt(69.1 * (m.Latitude - :latitude) * 69.1 * (m.Latitude - :latitude) +
                     53.0 * (m.longitude - :longitude) * 53.0 * (m.longitude - :longitude)) as Distance,
m.Latitude as Latitude, m.Longitude as Longitude
FROM table m
WHERE sqrt(69.1 * (m.Latitude - :latitude) * 69.1 * (m.Latitude - :latitude)
      + 53.0 * (m.longitude - :longitude) * 53.0 * (m.longitude - :longitude)) < :radius
ORDER BY  sqrt(69.1 * (m.Latitude - :latitude) * 69.1 * (m.Latitude - :latitude) +
          53.0 * (m.longitude - :longitude) * 53.0 * (m.longitude - :longitude)) desc
LIMIT 0, 100

這假設將返回特定半徑內的所有記錄(距離計算信息: http : //www.meridianworlddata.com/Distance-Calculation.asp

但是查詢需要很多時間...這是我得到的解釋計划:

id|select_type |table|type|possible_keys|key   |key_len|ref   |rows   |Extra
1 |SIMPLE      |m    |ALL |{null}       |{null}|{null} |{null}|1264001|Using where; Using filesort

我究竟做錯了什么? 我需要添加哪個索引才能使查詢使用它而不是表掃描? 我需要更改表結構嗎?

您在WHERE子句中使用函數,因此它將始終導致表掃描。 數據庫無法對函數結果建立索引。 我認為您最好的選擇是在嘗試評估距離算法之前想出一些方法來限制結果。

例如,對於給定的位置,您可以知道可能落在您設置的距離內的最小和最大緯度,因此請先過濾該緯度。 緯度約為69英里,因此,如果您的搜索半徑為50英里,則超過0.725緯度的任何地方都不可能落在您所在位置的50英里之內。 由於這只是一個數字比較,因此WHERE m.latitude > (:latitude - 0.725) AND m.latitude < (:latitude + 0.725)而不是對函數的調用,數據庫將能夠使用您的索引對其進行評估。

經度更加復雜,因為每個度數的距離都取決於該位置在北/南偏遠的地方,但是取決於您要投入多少工作量,您也可以對經度進行相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM