CALL for a procedure keeps loading, takes high CPU, and fails - mysql

I am trying to create a procedure that will take a view table , composed from thousands of records, and will filter it by removing several records according to various conditions.
When I try to use the CALL to run it, it keeps on loading, and according to WHM Panel, the process (phpMyAdmin/import.php) takes about 90% of CPU power.
Eventually it fails perhaps after 10 min due to a timeout:
Static analysis:
1 errors were found during analysis.
Missing expression. (near "ON" at position 25) SQL query: Edit Edit
SET FOREIGN_KEY_CHECKS = ON;
MySQL said: Documentation
2006 - MySQL server has gone away
I'm using the following code, and the new view table is using 3 DB tables:
vw_r2_items_tr, is using a tr DB core table, and a vw_items - a view table which uses items and visits core tables
DELIMITER $$
CREATE VIEW `vw_r2_items_tr` AS
SELECT
IF((`i`.`id` = `t`.`item_ord`),1,0) AS `has_tr`,
`i`.`calculated_score` AS `calculated_score`,
`i`.`visited_at` AS `visited_at`,
`i`.`ip_address` AS `ip_address`,
`i`.`user_id` AS `user_id`,
`i`.`visit_id` AS `visit_id`,
`i`.`product_id` AS `product_id`,
`i`.`name` AS `name`,
`i`.`id` AS `id`,
`i`.`item_no` AS `item_no`,
FROM (`vw_items` `i`
LEFT JOIN `trs` `t`
ON (((`t`.`visit_id` = `i`.`visit_id`)
AND (`t`.`item_ord` = `i`.`id`))))$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE `vw_unique_trs2`()
BEGIN
SET #vat=0;
SET #ht=0;
SET #tdiff=0;
-- EXPLAIN
SELECT
COUNT(*) AS ct,
tb1.* FROM (SELECT it.*, #tdiff:=UNIX_TIMESTAMP(CONVERT_TZ(it.visited_at,'+00:00',##global.time_zone)) AS tdiffs,
IF(#vat > 0 AND ((#vat-#tdiff) < 28800 AND (#vat-#tdiff) > -28800),#vat DIV 28800, #tdiff DIV 28800) AS diff,
#ht:=(IF(#vat > 0 AND ((#vat-#tdiff) < 28800 AND (#vat-#tdiff) > -28800),#ht+has_tr,has_tr)) hts,
#vat:=(IF(#vat > 0 AND ((#vat-#tdiff) < 28800 AND (#vat-#tdiff) > -28800),#vat,#tdiff)) curr_vat
FROM (SELECT * FROM (SELECT * FROM `vw_r2_items_tr` ORDER BY has_tr DESC, item_no, visited_at) AS tb
GROUP BY `tb`.`visit_id`,`tb`.`product_id`) AS it
ORDER BY has_tr DESC, it.visited_at DESC
) AS tb1
GROUP BY user_id, calculated_score, diff, hts;
END$$
DELIMITER ;

i think you cant use only one "ON" with two join, try to do 2 join query like that
`SELECT *
FROM Table1
LEFT JOIN Table2 ON Table1.key = Table2.key` and
LEFT JOIN Table3 ON Table1.key = Table2.key`

Related

Same SQL runs fast in QUERY but very slowly in SP?

I had tried to add or remove the '#' before variables or params but nothing happened.
QUERY
start transaction;
set #recordClient = (select ClientId from by_test_db1.recordcd where SN = 'abc' );
set #logClient = (select ClientId from by_test_db1.log where SN = 'abc' );
select concat(#recordClient,#logClient);
commit;
SP
delimiter $$
create procedure TEST(newSN varchar(50))
begin
start transaction;
set #recordClient = (select ClientId from by_test_db1.recordcd where SN = newSN );
set #logClient = (select ClientId from by_test_db1.log where SN = newSN );
select concat(#recordClient,#logClient);
commit;
end $$
delimiter ;
call TEST('abc');
MySQL version 5.7
Through there are 100 million rows in the recordcd table ,the QUERY just ran fast and well, but the SP was running so slowly that it timed out and reported an error
Error Code: 2013. Lost connection to MySQL server during query
I tried many ways but none of them worked, I don't know why there is such a ridiculous situation, I don't even know how to search the answer to this situation.
Add indexes
INDEX(SN) -- on both tables
Simplify query
SELECT CONCAT(
( select ClientId from by_test_db1.recordcd where SN = 'abc' ),
( select ClientId from by_test_db1.log where SN = 'abc' ) );

Procedure and multiple queries in MySql version 5.1.47

i have a stored procedure that delete a rows from 3 tables.
DROP procedure IF EXISTS `Epurer_Documents`;
DELIMITER $$
CREATE DEFINER=`dba_account`#`localhost` PROCEDURE `Epurer_Documents`(IN start_E INTEGER,IN pas_E INTEGER )
BEGIN
DELETE gdan from ged_document_annotation_individual as gdan
INNER JOIN ged_document_annotation as gda on gdan.id_ged_document_annotation=gda.id_ged_document_annotation
INNER JOIN ged_document as gd on gd.id_ged_document=gda.id_ged_document
INNER JOIN EpureridsgeFdolder as igf on gd.id_ged_folder = igf.id_ged_folderToEpurer
WHERE igf.id_ged_folderToEpurer in
(select id_ged_folderToEpurer from
( select id_ged_folderToEpurer from EpureridsgeFdolder limit start_E , pas_E) as x);
DELETE gdrs FROM ged_document_revision_seal as gdrs
INNER JOIN ged_document_revision as gdr on (gdrs.id_ged_document_revision_child=gdr.id_ged_document_revision
INNER JOIN EpureridsgeFdolder as igf on gd.id_ged_folder = igf.id_ged_folderToEpurer
WHERE igf.id_ged_folderToEpurer in
(select id_ged_folderToEpurer from
( select id_ged_folderToEpurer from EpureridsgeFdolder limit start_E , pas_E) as x);
DELETE FROM ged_folder WHERE id_ged_folder in ( select id_ged_folderToEpurer from ( select id_ged_folderToEpurer from EpureridsgeFdolder limit start_E , pas_E) as x);
END$$
DELIMITER ;
When i run it it show me a error :"" near , pas_E) as x); Delete gdrs From "",
but when i run it in a outher version of MySql it work juste fine.
so i wonder if the oldes version of mySQL doesn't support multiple queries in a stored procedure.
Thansk
Older MySQL version (<5.5.6) do not allow use of variables in LIMIT. Multiple queries in a stored procedure work just fine.

SQL query runs from IDE but not in phpmyadmin

I've got this SQL code:
CREATE EVENT `update_statistics`
ON SCHEDULE EVERY 1 DAY STARTS '2015-08-24 02:00:00'
ON COMPLETION PRESERVE
DO BEGIN
UPDATE statistics
SET km_traveled = (SELECT sum(km)
FROM archived_trips),
passengers_driven = (SELECT sum(passengers)
FROM archived_trips),
trips_taken = (SELECT count(*)
FROM archived_trips)
WHERE id = 1;
UPDATE statistics
SET co_saved = ((SELECT km_traveled
FROM statistics) * 0.215 * (SELECT passengers_driven
FROM statistics))
WHERE id = 1;
END;
When I run it through the SQL console in PhpStorm - it runs fine and the scheduled task works and so on.
But if I try to run the query directly in phpmyadmin, I get the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 13
Line 13 is WHERE id=1;. Honestly, I don't see any syntax problem with the query. Any suggestions?
The delimiter of the query is ';' and ';' is also used in the stored procedure, causing the query to fail.
Add DELIMITER // before the statement and end with // to fix this.
DELIMITER //
CREATE EVENT `update_statistics`
ON SCHEDULE EVERY 1 DAY STARTS '2015-08-24 02:00:00'
ON COMPLETION PRESERVE
DO BEGIN
UPDATE statistics
SET km_traveled = (SELECT sum(km)
FROM archived_trips),
passengers_driven = (SELECT sum(passengers)
FROM archived_trips),
trips_taken = (SELECT count(*)
FROM archived_trips)
WHERE id = 1;
UPDATE statistics
SET co_saved = ((SELECT km_traveled
FROM statistics) * 0.215 * (SELECT passengers_driven
FROM statistics))
WHERE id = 1;
END; //
DELIMITER ;
With PHPstorm, sending multiple queries in one go is probably disabled, causing MySQL to ignore the delimiter.
You must set the DELIMITER to other char. else they cant find out the end of the EVENT.
DELIMITER //
CREATE EVENT `update_statistics`
ON SCHEDULE EVERY 1 DAY STARTS '2015-08-24 02:00:00'
ON COMPLETION PRESERVE
DO BEGIN
UPDATE statistics
SET km_traveled = (SELECT sum(km)
FROM archived_trips),
passengers_driven = (SELECT sum(passengers)
FROM archived_trips),
trips_taken = (SELECT count(*)
FROM archived_trips)
WHERE id = 1;
UPDATE statistics
SET co_saved = ((SELECT km_traveled
FROM statistics) * 0.215 * (SELECT passengers_driven
FROM statistics))
WHERE id = 1;
END//
Shot in the dark, but try removing the semicolon after END.

Create Stored Procedure in MySQL

i have the following syntax for creating a stored procedure in MySQL 5.0.10
delimiter //
CREATE PROCEDURE getTweets (var1 varchar(100))
LANGUAGE SQL
SQL SECURITY DEFINER
COMMENT 'A procedure to return 20 least scored tweets based on the temp sessionid of the user'
BEGIN
SELECT count(ts.tweetid) as "count",t.id as "tweetid", t.tweettext as "tweet"
FROM tweets t
LEFT JOIN tweetscores ts ON t.id = ts.tweetid
where t.id not in (select distinct(tweetid) from tweetscores where temp_sessionid=var1)
group by t.id, t.tweettext order by count
LIMIT 10;
END//
i keep on getting the error
#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near '//' at line 12
can anybody spot the error..
Your query works when executing it as a script on DB level.
But using PhpMyAdmin you need remove the delimiter statement.
CREATE PROCEDURE getTweets (var1 varchar(100))
LANGUAGE SQL
SQL SECURITY DEFINER
COMMENT 'A procedure to return 20 least scored tweets based on the temp sessionid of the user'
BEGIN
SELECT count(ts.tweetid) as "count",t.id as "tweetid", t.tweettext as "tweet"
FROM tweets t
LEFT JOIN tweetscores ts ON t.id = ts.tweetid
where t.id not in (select distinct(tweetid) from tweetscores where temp_sessionid=var1)
group by t.id, t.tweettext order by count
LIMIT 10;
end
PhpMyAdmin will do the rest for you.
CREATE PROCEDURE getTweets (var1 varchar(100))
LANGUAGE SQL
SQL SECURITY DEFINER
COMMENT 'A procedure to return 20 least scored tweets based on the temp sessionid of the user'
BEGIN
SELECT count(ts.tweetid) as "count",t.id as "tweetid", t.tweettext as "tweet"
FROM tweets t
LEFT JOIN tweetscores ts ON t.id = ts.tweetid
where t.id not in (select distinct(tweetid) from tweetscores where temp_sessionid=var1)
group by t.id, t.tweettext order by count
LIMIT 10;
end

MySQL return to first record using LIMIT

Suppose:
$sql = " SELECT * FROM `artwork` WHERE approved = '1' ";
if($filter) $sql .= " AND $filter = '$filter_value' ";
$sql .= " ORDER BY subdate DESC, id DESC
LIMIT 30,30";
If I were to introduce a starting point (eg. WHERE id > 50) and that stipulation affected my LIMIT such that it only returned 10 results. I want 30 results, remember. Is there a way to start from record 1 and continue the selection?
edit: I realize I'm asking for id > 50 in this example and most certainly the first record if we were to rewind would have a lower ID. In my scenario that's okay.
Thanks, Jason.
If there are 100 records and you're
only selecting 10 rows (#90 - #100),
you want to get 20 more rows (#1 - #20)
If those are your constraints, I don't think you will be able to get the desired result set from a single query.
Here's a stored procedure which creates a temp table to get the desired result:
DELIMITER //
DROP PROCEDURE IF EXISTS TMP_TABLE_ARTWORK//
CREATE PROCEDURE TMP_TABLE_ARTWORK (_offset INT, _count INT)
BEGIN
DECLARE res_total INT DEFAULT 0;
SELECT COUNT(*) INTO res_total FROM artwork;
CREATE TEMPORARY TABLE IF NOT EXISTS artwork_tmp ( t_pseudo INT, t_old INT, t_subdate DATETIME );
INSERT INTO artwork_tmp ( t_pseudo, t_old, t_subdate ) SELECT artwork.id, artwork.id, artwork.subdate FROM artwork ORDER BY artwork.subdate DESC;
INSERT INTO artwork_tmp ( t_pseudo, t_old, t_subdate ) SELECT ( artwork.id + res_total ), artwork.id, artwork.subdate FROM artwork ORDER BY artwork.subdate DESC;
PREPARE STMT FROM "SELECT * FROM artwork_tmp ORDER BY t_pseudo LIMIT ?,?";
SET #offset = _offset;
SET #count = _count;
EXECUTE STMT USING #offset, #count;
DROP TABLE artwork_tmp;
END //
DELIMITER ;
You'll probably need to modify it to get it to do what you want (and apparently the prepared statement workaround is no longer required if you're running a newer version of MySQL).
If I understand your question.
You should use LIMIT 0, 30 to get first 30 records which match your query.