SQL存储过程速度问题

时间:2019-04-01 20:22:31

标签: mysql sql query-performance

我有一个存储过程,它用于获取两个日期之间10表上的数据。它返回的行数超过1000。当我在网站上调用此过程时,有时会返回“网站不响应”错误。我应该如何优化这个问题。

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/full_screen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="72sp"
    android:gravity="center"
    android:transitionName="random"
    android:background="@color/colorAccent"/>

4 个答案:

答案 0 :(得分:2)

好的,在我看来,主要有几种可能性:

可能性#1:缺少索引

想象一下,您的表在该日期字段上没有任何索引。因此,如果您想查找与查询匹配的记录,则SQL引擎必须浏览整个表以查找其查找内容!索引背后的想法是,它可以快速二进制查找匹配的记录

可能性2:未使用索引

这有点难以诊断。您必须使用MySql提供的任何查询分析工具(我对此并不熟悉)才能弄清楚。但是,基本上,如果您有一个查询,其中索引将返回太多行而不值得的引擎内容,则无论如何它只会使用主表。例如,想象做一个LastName!=“ Thomas”。为什么要使用索引找出要返回的行的99%,然后尝试将其与主表进行匹配?不,它只是使用主表开始的。

可能性3:数据过多

问题可能在于它只是返回了很多数据。您在其中有了SELECT *-它会返回表中的每一个列。这不仅是不好的设计(如果添加/插入列会怎样?),这还意味着它必须传递可能甚至没有被使用的数据。

编辑:可能性4:需要合并索引

我第一次误读了语句的一部分,并假设p_dt_bas和p_dt_bts值是来自前端的变量,而不是表中的其他列。在这种情况下,还有另一种可能性:它不能使用任何现有索引,因为它们不包含所有信息。毕竟,如果您有一个ColA = ColB的查询并且在每列上都有单独的索引...则不能使用这些索引。毕竟,索引只是其中的一种小型表:{索引列,指向主表的指针}。因此,使用{ColA,指针}的索引不会帮助您在ColA = ColB的位置查找值。您需要在相同索引中使用ColB。同样,对于A

答案 1 :(得分:0)

像Peter上面所说的那样,在vade_tarihi列中添加索引会有所帮助。将索引添加到p_dt_bas和p_dt_bts列也将是有益的。

是否有必要提取这些表中的所有列?仅选择所需的列(如果不需要)也可以提高速度,因为这会减小查询返回的整体大小。

如果此后查询仍然很慢,则也可以考虑使用vade_tarihi列对表进行分区。这将使查询优化器只能将其视为与查询相关的数据子集。

如果这些选项不起作用,请考虑允许数据库使用更多ram进行缓存。

答案 2 :(得分:0)

确保在p_dt_bas和p_dt_bts上有一个索引。您也可以在where子句中使用BETWEEN运算符,而不是进行两次比较。

BEGIN
    SELECT * FROM banka_cariodeme 
        WHERE vade_tarihi between p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM banka_caritahsilat 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM kasa_cariodeme 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM kasa_caritahsilat 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM cek_cariodeme 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM cek_caritahsilat 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM pos_cariodeme 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM pos_caritahsilat 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM senet_cariodeme 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
    SELECT * FROM senet_caritahsilat 
        WHERE vade_tarihi BETWEEN p_dt_bas AND p_dt_bts 
        ORDER BY  vade_tarihi DESC;
END

答案 3 :(得分:0)

EXPLAIN EXTENDED SELECT * FROM banka_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;

将是一个好的开始,并将提供一些有关数据库和索引的信息...