Mysql slow performance of very simple SELECT stored procedures - mysql

I am calling a stored procedure from JAVA, and it runs very slowly (about 120ms), even if it doesn't do much. For example:
BEGIN
SELECT '1';
END
If I have the stored procedure do literally nothing, or if I run the select commands outside of a stored procedure (ie execute the select * from.. directly in code), then it runs quickly (3ms or so).
BEGIN
END
I have 50 other SELECT stored procedures, and they all run equally slowly. If I run any if these commands outside of stored procedures (ie execute the SELECT * FROM... statement from JAVA without stored procedures), then they run very quickly.
I did look around and found others with similar issues, but couldn't find an answer that works in my case. I confirmed that collation and character set are the same between the database, the table, and the stored procedure.
INSERTS seem to run quickly. It really seems isolated to SELECT commands.
Environment: FreeBSD 10.3, DB - MariaDB 10.0.21
EDIT: Running the stored procedures from mysql commandline executes very quickly (0.00 sec).
EDIT: I enabled the general log and have the following output:
184381 Connect qwkdb#localhost as anonymous on productdb
184381 Query /* mysql-connector-java-6.0.2 ( Revision: c6da0fe501ad43d4ed6483b60ea796dc9fbe2d7b ) */SELECT ##session.auto_increment_increment AS auto_increment_increment, ##character_set_client AS character_set_client
, ##character_set_connection AS character_set_connection, ##character_set_results AS character_set_results, ##character_set_server AS character_set_server, ##init_connect AS init_connect, ##interactive_timeout AS interactive_timeout, ##l
icense AS license, ##lower_case_table_names AS lower_case_table_names, ##max_allowed_packet AS max_allowed_packet, ##net_buffer_length AS net_buffer_length, ##net_write_timeout AS net_write_timeout, ##query_cache_size AS query_cache_size
, ##query_cache_type AS query_cache_type, ##sql_mode AS sql_mode, ##system_time_zone AS system_time_zone, ##time_zone AS time_zone, ##tx_isolation AS tx_isolation, ##wait_timeout AS wait_timeout
184381 Query SET NAMES latin1
184381 Query SET character_set_results = NULL
184381 Query SET autocommit=1
184381 Query SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'
184381 Query SELECT name, type, comment FROM mysql.proc WHERE name like 'GetAttributeValue' and db <=> 'productdb' ORDER BY name, type
184381 Query SHOW CREATE PROCEDURE productdb.GetAttributeValue
184381 Query CALL GetAttributeValue('hi')

Related

Incorrect string value via stored procedure on Mysql

Adjusting some of the table columns to support emojis on mysql 8. I successfully managed to update character set and collation to unicode utf8mb4 and utf8mb4_unicode_520_ci
When I test it with plain Insert and select queries I can able to see that emojis are successfully inserted. Problem happens when I try to use existing stored procedure to modify column it fails. Regardless of the client calls SP Scala app, Datagrip or mysql client I get same error Incorrect string value: '\xF0\x9F\x98\x85\xF0\x9F...' for column 'data'
I tried several things such as setting charset runtime before running SP and also inside the SP, adjusted SP input parameters with charset as well with no luck. Sharing stored procedure here as well to show whether I'm missing something or not but running out of ideas what can be wrong.
DROP PROCEDURE IF EXISTS deploy_scenario;
DELIMITER $$
CREATE PROCEDURE deploy_scenario (
IN scenarioId INT,
IN datax LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci,
IN creationDate DATETIME
)
BEGIN
DECLARE currentVersion INT;
SET CHARACTER SET utf8mb4;
# Get current version
SELECT IFNULL((SELECT version from scenario_version where scenario_id = scenarioId ORDER BY version DESC LIMIT 1),0)
INTO currentVersion;
# Increase current version
SET currentVersion = currentVersion + 1;
INSERT INTO scenario_version
(scenario_id, version, data, creation_date) VALUES
(scenarioId, currentVersion, datax, creationDate);
INSERT INTO engine_scenario VALUES (scenarioId,currentVersion,datax,creationDate)
ON DUPLICATE KEY UPDATE data = datax,deployed_version= currentVersion, last_op_date=creationDate;
UPDATE scenario SET status='DEPLOYED' WHERE id = scenarioId;
SELECT currentVersion;
END $$
DELIMITER ;
Here is the column details if It helps;

Long running SELECT with UPDATE locks database

I have a select statement that takes a long time to run (around 5 minutes). Because of this I only run the query every hour and save the results to a metadata table. Here is the query:
UPDATE `metadata` SET `value` = (select count(`id`) from `logs`) WHERE `key` = 'logs'
But this is the issue I have been having (And correct me if I am wrong). A select statement does not lock the database, but an update statement does. Now since I am running this long ruining select query inside of the update query, it ends up locking the DB for about 5 minutes.
Is there a better way to do this to run the select statement and save it to a variable and then once that is done then running the update query? This way it wont lock the DB.
Also note I don't care about dirty data.
The database has over 300 million rows and has data being added to it constantly.
Just to avoid the possibility that the server disconnects between the statement getting the count and the statement storing it, leaving your variable unset, beginning in mariadb 1.1 you can run multiple statements in a single request by putting them in a block:
begin not atomic
declare `logs_count` int;
select count(*) into `logs_count` from `logs`;
update `metadata` set `value`=`logs_count` where `key`='logs';
end
fiddle
I have found that setting this before the query runs seems to work and runs a whole lot faster. This should keep the DB from locking when executing the query. We then enable locking after it has completed.
(Please correct me if I have done something incorrect here)
BEGIN
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE `metadata` SET `value` = (select count(`id`) from `logs`) WHERE `key` = 'logs';
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
END

MySQL variable is NULL after it was set

I set a variable in MySQL and in the next SELECT query it is NULL.
SET #test = 123;
SELECT #test;
When executing the SET statement, there is no error.
Do I have to enable/activate the usage of variables?
I run MySQL Server 4.1.

MySQL too many prepared statements

Is there a way to see what the prepared statements are that are associated with this error:
(OperationalError) failed to prepare the MySQL query:
Can't create more than max_prepared_stmt_count statements (current value: 20000)
One of several processes might be responsible for this problem and I'm trying to figure out which one it could be the easiest way I can think of, which is to see the text of the prepared statements and track it back to the source.
Is there any way to see what these prepared statements are so I can find the guilty party?
To see how many prepared statements are currently open, you can run:
SHOW GLOBAL STATUS LIKE 'com_%prepare%';
Which gives you something like:
Variable_name | Value
-------------------+--------
Com_prepare_sql | 2
Com_stmt_prepare | 2
Com_stmt_reprepare | 0
Com_xa_prepare | 0
To read the actual statements, you will need to look in the general query log for a while, and then read from it.
I like using a table for the general log:
-- set up
TRUNCATE TABLE mysql.general_log;
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
-- wait for some time
SET GLOBAL general_log = 'OFF';
-- read results
SELECT * FROM mysql.general_log WHERE argument LIKE 'prepare%' OR argument LIKE 'execute%';
You can see statements being prepared and executed:
command_type | argument
-------------+--------------------------------------------------------
Query | prepare st from "select * from people where name = ?"
Query | execute st Using #name

Why this stored procedure return an empty result?

I have a stored procedure that it works correctly on localhost but when i tried to execute that on my vps server, i give an empty result.
CREATE PROCEDURE `sp_contest_selectContestId`(
IN _uniquetitle VARCHAR(300))
BEGIN
SELECT `id`
FROM `contest`
WHERE
`uniquetitle` = _uniquetitle
LIMIT 0, 1
;END
When i use this part without using procedure with the same data to test, i have not any problem:
SELECT `id`
FROM `contest`
WHERE
`uniquetitle` = _uniquetitle
LIMIT 0, 1
I was using UTF-8 data. My tables was UTF8 but not my database. database was latin_swedish.
I change my database collation to UTF8 and then import my data again. problem solved.
I had to set mydatabase collation to UTF-8 befor insert or import any things.