Sql存储过程速度问题

问题描述 投票:0回答:4

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

BEGIN
SELECT * FROM banka_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM banka_caritahsilat WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM kasa_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM kasa_caritahsilat WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM cek_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM cek_caritahsilat WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM pos_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM pos_caritahsilat WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM senet_cariodeme WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
SELECT * FROM senet_caritahsilat WHERE (vade_tarihi >= p_dt_bas) AND (vade_tarihi <= p_dt_bts) ORDER BY vade_tarihi DESC;
END
mysql sql query-performance
4个回答
2
投票

好吧,我脑子里似乎有几个主要的可能性:

可能性#1:缺少索引

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

可能性#2:未使用索引

这个诊断有点困难。你必须使用MySql给你的任何查询分析工具(我不熟悉那个)来弄明白。但是,基本上,如果你有一个查询引擎的东西,索引将返回太多的行值得它,它只会使用主表。例如,想象做一个LastName!=“Thomas”。为什么它会使用索引来确定99%的行将被返回,然后尝试将它与主表匹配?不 - 它只是使用主表开始。

可能性#3:太多数据

可能问题在于它只是返回了大量数据。你在那里有SELECT * - 它将返回表中的每一列。这不仅是糟糕的设计(如果添加/插入列会怎么样?)但这意味着它必须传回可能甚至无法使用的数据。

编辑:可能性#4:需要综合指数

我第一次误读了部分语句,并假设p_dt_bas和p_dt_bts值是前端的变量而不是表中的其他列。在这种情况下,还有另一种可能性:它不能使用任何现有索引,因为它们不包含所有信息。毕竟,如果你有一个ColA = ColB的查询和每列上的单独索引......它就不能使用索引。毕竟,索引只是一种迷你表:{indexed columns(s),指向主表的指针}。因此,使用{ColA,pointer}的索引无助于找到ColA = ColB的值。您需要将ColB放在同一个索引中。同样,对于A <B <C的查询,您需要一个包含所有三列的索引。重要说明:此类查询仍无法实现二进制查找性能。但它只能扫描索引 - 而不是全表扫描。根据您的表有多少列,这仍然是一个非常重要的加速。


0
投票

正如彼得所说,在vade_tarihi列中添加索引会有所帮助。将索引添加到p_dt_bas和p_dt_bts列也是有益的。

是否有必要拉出这些表中的所有列?仅选择所需的列(如果没有)可能有助于提高速度,因为这会减少查询返回的总体大小。

如果查询仍然很慢,那么通过vade_tarihi列对表进行分区也可能需要考虑。这将允许查询优化器仅查看与查询相关的数据子集。

如果这些选项不起作用,请考虑允许db使用更多ram进行缓存(如果可以)。


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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.