| Bug #36694 | bad information_schema performance in .NET app running stored routines | ||
|---|---|---|---|
| Submitted: | 13 May 2008 18:20 | Modified: | 11 Jul 2008 18:34 |
| Reporter: | Bogdan Degtyariov | ||
| Status: | Closed | ||
| Category: | Connector/Net | Severity: | S3 (Non-critical) |
| Version: | OS: | Microsoft Windows | |
| Assigned to: | Bogdan Degtyariov | Target Version: | |
| Tags: | stored procedure, .net, performance, information_schema | ||
[13 May 2008 18:29]
Bogdan Degtyariov
Patch from "\tags\5.2.1\"
Attachment: patch36694.diff (application/octet-stream, text), 5.39 KiB.
[23 May 2008 18:05]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/47005
[23 May 2008 18:05]
Reggie Burnett
Fixed in 5.2.3. Here is the change log entry Changed how the procedure schema collection is retrieved. If 'use procedure bodies=true' then we select on the mysql.proc table directly as this is up to 50x faster than our current IS implementation. If 'use procedure bodies=false', then the IS collection is queried.
[8 Jul 2008 18:28]
Tony Bedford
Are 'use procedure bodies=true' and 'use procedure bodies=false' new options? How are these set by the user? Is there a small piece of example code that can illustrate this please?
[8 Jul 2008 19:43]
Reggie Burnett
They are connection string options. They are set by adding them to your connection string. Here is an example: string connStr = "server=localhost;user id=root;database=test;use procedure bodies=true"; MySqlConnection c = new MySqlConnection(connStr); c.Open();
[11 Jul 2008 18:34]
Tony Bedford
An entry has been added to the 5.2.3 changelog: Changed how the procedure schema collection is retrieved. If the connection string contains “use procedure bodies=true” then a select is performed on the mysql.proc table directly, as this is up to 50 times faster than the current Information Schema implementation. If the connection string contains “use procedure bodies=false”, then the Information Schema collection is queried.
[25 Jul 2008 13:17]
Tonci Grgin
More comments and full test case in Bug#36376

Description: .NET application demonstrates appalling delays when running stored procedures. These delays are not significant for a small number of stored procedures defined for a database. However, once the number is really big (>5000), every call takes not less than 800-1000 milliseconds. Also, the delays occur only for the first call of the procedure not yet executed within the current connection. If the application runs different procedures it has to wait for 1000 ms for every call, which is more than 1,5 hours. All this time Connector/NET is waiting on metadata from information_schema (actually it is a "SELECT * FROM INFORMATION_SCHEMA..." query). Before running the stored procedure C/NET has to check IN/OUT parameters and initialize hash structures using the metadata. Consequently, the server query log contains lots of slow queries selecting metadata as follows: SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='test9' AND ROUTINE_NAME='spa3470' Execution time is 1020 ms. The same data can be retrieved from mysql.proc table, but execution time is 20 ms - more than 50 times faster! Even though there is a workaround that helps .NET applications overcoming the stored procedures performance issues, the problem is in the server implementation of information_schema (so, later this report has to be qualified as server/I_S bug). How to repeat: 1. Create 10000 stored procedures. Procedures can do the same, but should have different names. For example: DELIMITER $$ CREATE PROCEDURE `spa1001`(IN param1 INT, OUT param2 INT) BEGIN SELECT COUNT(*) INTO param2 FROM testtab where id>param1; END$$ DELIMITER ; 2. Run the procedure using MySqlCommand class instance: cmd = new MySqlCommand(); cmd.Connection = conn; cmd.CommandText = "spa1001"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("?param1", "3"); cmd.Parameters["?param1"].Direction = ParameterDirection.Input; cmd.Parameters.Add("?param2", MySqlDbType.Int32); cmd.Parameters["?param2"].Direction = ParameterDirection.Output; cmd.ExecuteNonQuery(); // This line takes 1000 ms to accomplish Suggested fix: Connector/NET has an option "Use Procedure Bodies" indicating that the user connecting to the database havs the SELECT privileges for the mysql.proc (stored procedures) table. So, if the option is set to TRUE, it is safe to query mysql.proc directly and take the advantage of greater performance. The patch is uploaded below.