Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Order By with函数计算两点之间的距离时MySQL查询速度慢(长,纬度)_Mysql_Database_Sorting - Fatal编程技术网

使用Order By with函数计算两点之间的距离时MySQL查询速度慢(长,纬度)

使用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给定的常量,并且每次运行查询时都不同 函数本身的速度不是

我在MySQL中有一个查询,它在表的每一行上运行一个存储函数,然后根据函数的结果对行进行排序,然后返回前10行

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
选项:
  • 将排序合并到存储过程中 定义/逻辑。如果在存储过程中调用SQL select,请在存储过程中执行排序和限制-这意味着您将不会在存储过程中生成10000行,而只是使用它们。而且,若表中有索引,那个么在SQL select中进行原始排序可能会快得多

  • 验证您的表中是否使用了索引。-在表中选择时,索引将使您的排序执行得更快

  • 请向我们提供函数定义,以便为您提供更多帮助。

    最后,尝试在函数中直接移动和限制您的订单,而不是稍后再执行。您的函数可以返回直接排序并准备好的10个结果。 如果需要,可以创建两个函数—一个返回完整结果,另一个返回有限和排序结果

    更新: 看到函数后,很明显,您试图按计算值排序。按计算值排序非常慢,如中所述:

    我试图思考如何基于col1或col2对数据进行“预处理/排序”,以加快结果的最终排序。如果col1和col2是表的列,而funResult是一个可以用图形表示的数学函数,那么这两个函数中的一个对函数返回值的影响更大

    最后,如果col1和col2是myTable的列,则不需要使用存储函数,但可以使用进行查询,但这不会有太大区别……您的主要问题是按计算函数排序:

    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的不同变体。当我删除
    顺序时,我也删除了
    限制
    ,以便为每一行运行该函数。对不起,我试图使函数更简单-我已经更新它以显示实际的函数