1

このクエリを使用しましたが、mysqlが結果を出すのに時間がかかりすぎました。行数は160万行です。

SELECT DISTINCT TB.ID,  Latitude, Longitude,
    111151.29341326*SQRT(pow(-6-`Latitude`,2)
        +pow(106-`Longitude`,2)*cos(-6*0.017453292519943)
        *cos(`Latitude`*0.017453292519943)) as Distance  
FROM `tablebusiness` AS TB, `tablecity` AS TC, `businessestag` AS BC,
    `businessesdistricts` AS BD, `tabledistrict` AS TD, 
     (SELECT ID, 
         (SELECT Title 
            FROM `tablebusiness` As TBuild 
           WHERE TBuild.ID = TBB.Building) As BuildingTitle 
      FROM `tablebusiness` As TBB) AS TBuilding  
WHERE TB.City = TC.City AND BC.BusinessID = TB.ID AND BD.BusinessID = TB.ID 
  AND TD.ID = BD.District AND TBuilding.ID = TB.ID 
  AND (`Title` LIKE '%%' OR `Street` LIKE '%%'  OR TB.City LIKE '%%' 
       OR Country LIKE '%%' OR Tag LIKE '%%' OR TD.District LIKE '%%' 
       OR TBuilding.BuildingTitle LIKE '%%') 
  AND (-6.0917668133836 < `Latitude` AND `Latitude` < -5.9082331866164 
       AND 105.90823318662 < `Longitude` AND `Longitude` < 106.09176681338)  
ORDER BY Distance LIMIT 0, 100

行数はクエリの160万部分ですが、

AND (-6.0917668133836 < `Latitude` AND `Latitude` < -5.9082331866164 AND 105.90823318662 < `Longitude` AND `Longitude` < 106.09176681338) 

行数を大幅に制限します。mysqlが検索してクエリを最適化することを気にしないようです

AND (-6.0917668133836 < `Latitude` AND `Latitude` < -5.9082331866164 AND 105.90823318662 < `Longitude` AND `Longitude` < 106.09176681338) first.

前面の緯度経度アスペクトを移動してクエリを変更しました

SELECT DISTINCT TB.ID,  Latitude, Longitude,
    111151.29341326*SQRT(pow(-6-`Latitude`,2)
        +pow(106-`Longitude`,2)*cos(-6*0.017453292519943)
        *cos(`Latitude`*0.017453292519943)) as Distance  
FROM `tablebusiness` AS TB, `tablecity` AS TC, `businessestag` AS BC,
    `businessesdistricts` AS BD, `tabledistrict` AS TD, 
     (SELECT ID, 
         (SELECT Title 
            FROM `tablebusiness` As TBuild 
           WHERE TBuild.ID = TBB.Building) As BuildingTitle 
      FROM `tablebusiness` As TBB) AS TBuilding
WHERE (-6.0917668133836 < `Latitude` AND `Latitude` < -5.9082331866164 
       AND 105.90823318662 < `Longitude` AND `Longitude` < 106.09176681338) 
  AND TB.City = TC.City AND BC.BusinessID = TB.ID AND BD.BusinessID = TB.ID 
  AND TD.ID = BD.District AND TBuilding.ID = TB.ID 
  AND (`Title` LIKE '%%' OR `Street` LIKE '%%'  OR TB.City LIKE '%%' 
       OR Country LIKE '%%' OR Tag LIKE '%%' OR TD.District LIKE '%%' 
       OR TBuilding.BuildingTitle LIKE '%%')
ORDER BY Distance LIMIT 0 ,100

それでも同じくらい遅いです。

それならどうすればいいですか?

4

4 に答える 4

1

クエリの一部を検索するには、インデックスを使用する必要があります。したがって、インデックスが必要です。MySQLには(地理)空間データの拡張機能があるため、それを検索してRツリーインデックスを使用する必要があります。これは、2列の範囲制限に最も効率的な種類です。

于 2012-05-31T07:24:49.547 に答える
1

経度と経度の列にBTreeインデックスがありますか?

于 2012-05-31T07:27:20.143 に答える
1

explain select ...show create table tablebusiness \G言って?

MySQLが範囲クエリにインデックスを使用する方法にはいくつかの制限があります。必ずそれを読んでください。

多くのユースケースでの私の経験では、MySQLではbツリーインデックスを使用する方が空間インデックスよりも効率的です。経度と緯度を整数に変更することをお勧めします(「小数」を取得するには適切な数値を掛けて、両方の列にまたがるインデックスがあることを確認してください(alter table tablebusiness add index latlon (latitude,longitude))。

于 2012-05-31T07:38:08.493 に答える
1

本当にtablebusinessFROM句にテーブルを3回含める必要がありますか?これを書き直して、JOINを使用しました。WHERE条件を確認してください。TitleLIKE'%%'とは何ですか?この簡略化されたクエリを試してください-

SELECT
  TB.ID,
  Latitude,
  Longitude,
  111151.29341326 * SQRT(POW(-6 - `Latitude`, 2) + POW(106 - `Longitude`, 2) * COS(-6 * 0.017453292519943) * COS(`Latitude` * 0.017453292519943)) AS Distance
FROM
  `tablebusiness` AS TB
  JOIN `tablecity` AS TC
    ON TB.City = TC.City
  JOIN `businessestag` AS BC
    ON BC.BusinessID = TB.ID
  JOIN `businessesdistricts` AS BD
    ON BD.BusinessID = TB.ID
  JOIN `tabledistrict` AS TD
    ON TD.ID = BD.District
  LEFT JOIN `tablebusiness` TBuilding
    ON TBuilding.ID = TB.ID
WHERE
  (`Title` LIKE '%%' OR `Street` LIKE '%%' OR TB.City LIKE '%%' OR Country LIKE '%%'
    OR Tag LIKE '%%' OR TD.District LIKE '%%' OR TBuilding.BuildingTitle LIKE '%%')
  AND (-6.0917668133836 < `Latitude` AND `Latitude` < -5.9082331866164 
    AND 105.90823318662 < `Longitude` AND `Longitude` < 106.09176681338) 
ORDER BY
  Distance
LIMIT
  0, 100

JOIN句とWHERE句で使用されるフィールドにインデックスを追加すると、クエリも高速化されます。

于 2012-05-31T07:46:41.007 に答える