mysql stored procedure is slower 20 times than standard query

前端 未结 4 352
梦谈多话
梦谈多话 2020-12-16 13:33

i have 10 tables with same structure except table name.

i have a sp (stored procedure) defined as following:

 select * from table1 where (@param1 IS          


        
相关标签:
4条回答
  • 2020-12-16 14:03

    I had seen this behavior, but it wasn't related to the character set.

    I had a table that held self-referencing hierarchical data (a parent with children, and some children had children of their own, etc.). Since the parent_id had to reference the primary id's (and the column specified a constraint to that effect), I couldn't set the parent id to NULL or 0 (zero) to disassociate a child from a parent, so I simply referenced it to itself.

    When I went to run a stored procedure to perform the recursive query to find all children (at all levels) of a particular parent, the query took between 30 & 40 times as long to run. I found that altering the query used by the stored procedure to make sure it excluded the top-level parent record (by specifying WHERE parent_id != id) restored the performance of the query.

    The stored procedure I'm using is based on the one shown in: https://stackoverflow.com/questions/27013093/recursive-query-emulation-in-mysql.

    0 讨论(0)
  • 2020-12-16 14:04

    Interesting question, because I am fond of using stored procedures. Reason is maintenance and the encapsulation principle.

    This is information I found: http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html

    It states that the query cache is not used for queries that 1. are a subquery that belong to an outer query, and 2. are executed within the body of a stored procedure, trigger or event.

    This implies that it works as designed.

    0 讨论(0)
  • 2020-12-16 14:07

    Just a guess:

    When you run the query by hand, the expression WHERE ('test' IS NULL or COL1 = 'test') can be optimized when the query is being parsed. The parser can see that the string 'test' is not null, so it converts the test to WHERE COL1 = 'test'. And if there's an index on COL1 this will be used.

    However, when you create a stored procedure, parsing occurs when the procedure is created. At that time, it doesn't know what @param will be, and has to implement the query as a sequential scan of the table.

    Try changing your procedure to:

    IF @param IS NULL
    THEN BEGIN
      SELECT * FROM table1
      UNION ALL
      SELECT * FROM table2
      ...
    END;
    ELSE BEGIN
      SELECT * FROM table1 WHERE col1 = @param
      UNION ALL
      SELECT * FROM table2 WHERE col1 = @param
      ...
    END;
    END IF;
    

    I don't have much experience with MySQL stored procedures, so I'm not sure that's all the right syntax.

    0 讨论(0)
  • 2020-12-16 14:19

    Possible character set issue? If your table character set is different from your database character set, this may be causing a problem.

    See this bug report: http://bugs.mysql.com/bug.php?id=26224

    [12 Nov 2007 21:32] Mark Kubacki Still no luck with 5.1.22_rc - keys are ingored, query takes within a procedure 36 seconds and outside 0.12s.

    [12 Nov 2007 22:30] Mark Kubacki After having changed charsets to UTF-8 (especially for the two used), which is used for the connection anyways, keys are taken into account within the stored procedure!

    The question I cannot answer is: Why does the optimizer treat charset conversions an other way within and outside stored procedures? (Indeed, I might be wrong asking this.)

    0 讨论(0)
提交回复
热议问题