使用Order By with函数计算两点之间的距离时MySQL查询速度慢(长,纬度)
我在MySQL中有一个查询,它在表的每一行上运行一个存储函数,然后根据函数的结果对行进行排序,然后返回前10行使用Order By with函数计算两点之间的距离时MySQL查询速度慢(长,纬度),mysql,database,sorting,Mysql,Database,Sorting,我在MySQL中有一个查询,它在表的每一行上运行一个存储函数,然后根据函数的结果对行进行排序,然后返回前10行 SELECT rowId, MyFunction(x, y, constX, constY) AS funResult FROM myTable ORDER BY funResult DESC LIMIT 10 问题是,在一个包含10000行的表上运行需要几秒钟,这太慢了。函数的结果无法计算并存储为表中的另一行,因为它采用PHP给定的常量,并且每次运行查询时都不同 函数本身的速度不是
SELECT rowId, MyFunction(x, y, constX, constY) AS funResult
FROM myTable
ORDER BY funResult DESC
LIMIT 10
问题是,在一个包含10000行的表上运行需要几秒钟,这太慢了。函数的结果无法计算并存储为表中的另一行,因为它采用PHP给定的常量,并且每次运行查询时都不同
函数本身的速度不是问题,因为删除funResult DESC LIMIT 10的命令意味着查询运行时间不到0.01秒
问题一定是对行进行排序——考虑到只需要前10行,是否有任何方法可以更快地进行排序
更新
使用的简化函数计算每行与指定点之间的距离(其中LAT_B和LON_B是常数,取决于查询):
试试这个
SELECT rowId, MyFunction(col1, col2, constant) AS funResult
FROM myTable
ORDER BY MyFunction(col1, col2, constant) DESC
LIMIT 10
选项:
SELECT rowId, ((col1-INPUT_CONST)*2)+(col2*3) AS funResult
FROM myTable
ORDER BY funResult DESC
LIMIT 10
MyFunction(col1, col2, constant) = (col1 - constant) * 2.0 + col2 * 3.0
= 2*col1 + 3*col2 - 2*constant
更新2:
在对排序问题进行挖掘之后,我发现在下面的链接中,这一问题得到了非常有效的解决。相对于按计算值排序,按计算值排序本质上是缓慢的。有关其他帮助,请参见以下两个链接:
- -“在mysql查询中优化距离计算 "
- 李>
我想您的问题在于执行函数所需的时间。如果执行此查询:
SELECT rowId, MyFunction(col1, col2, constant) AS funResult
FROM myTable
LIMIT 10
SELECT rowId, MyFunction(col1, col2, constant) AS funResult
FROM myTable
ORDER BY funResult DESC
LIMIT 10
数据库必须:
- 计算10行的函数结果
- 返回这10行
SELECT rowId, MyFunction(col1, col2, constant) AS funResult
FROM myTable
LIMIT 10
SELECT rowId, MyFunction(col1, col2, constant) AS funResult
FROM myTable
ORDER BY funResult DESC
LIMIT 10
数据库必须
- 计算表中所有10000行的函数结果
- 排序10000行
- 返回前10行
因此,要真正了解您的函数是否是瓶颈,您应该确保实际计算这两个查询的所有10000行的函数结果,并检查差异是否仍然存在。扩展函数:
SELECT rowId, ((col1-INPUT_CONST)*2)+(col2*3) AS funResult
FROM myTable
ORDER BY funResult DESC
LIMIT 10
MyFunction(col1, col2, constant) = (col1 - constant) * 2.0 + col2 * 3.0
= 2*col1 + 3*col2 - 2*constant
然后您的选择变成:
SELECT rowId, tmpResult - 2*constant AS funResult
FROM myTable
ORDER BY tmpResult DESC
LIMIT 10
在mysql中实现这一点实际上要快得多
3956*2*ASIN(SQRT(POWER(SIN(LAT_A-abs(LAT_B))*pi()/180/2),2)+COS(LAT_A*pi()/180)*COS(abs(LAT_B)*pi()/180)*POWER(SIN(LON_A-LON_B)*pi()/180/2));
而不是通过自定义函数进行排序
这很难看,但速度要快得多
试着解释一下。
出于某种原因,mysql在涉及函数时使用临时表,但在涉及数学时不使用临时表。请显示您的函数定义。是的,我们还应该查看您的函数定义。尝试将订单移动到函数中并直接限制,而不是稍后再执行。您的函数可以直接返回10个排序结果并准备就绪。myTable的col1和col2列是吗?在返回中,我怀疑乘法优先于加法,所以您想将col2*3添加到tempCalc?@user882807我认为您最有效的选择是这样做:我想检查它是否对避免别名有显著影响…谢谢-我已经添加了函数定义,但我不知道如何添加将排序和限制合并到定义中,以避免再次发生罢工。唉+1.坚持不懈;我怀疑你所链接的其中一个问题中的空间索引方法可能是最好的解决方法。@eggyal完全。。。当用户问Y时,这种情况会发生很多次,漏掉了大量的细节…最后你意识到他真的在问Z,这可能是已经问过/回答过的问题a的不同变体。当我删除顺序时,我也删除了限制
,以便为每一行运行该函数。对不起,我试图使函数更简单-我已经更新它以显示实际的函数