Optimize MySQL query because it gets time out - mysql

Can anyone help me with optimizing this query. I can not execute it because phpMyAdmin connection gets timed out and i have no access to change time out parameter.
Here is a query:
INSERT INTO `goods` (`goods_id`, `price`, `name`)
SELECT `sales_goods`.`goods_id`, `sales_goods`.`price`, `sales_goods`.`goods_id`
FROM `sales_goods`
WHERE `sales_goods`.`sales_goods_id`
IN (
SELECT MAX(`sales_goods`.`sales_goods_id`)
FROM `sales_goods`
WHERE `sales_goods`.`sales_goods_id`
IN (
SELECT `sales_goods`.`sales_goods_id` FROM `sales_goods`
WHERE `sales_goods`.`goods_id` NOT IN (SELECT `goods`.`goods_id` FROM `goods`)
)
GROUP BY `sales_goods`.`goods_id`
)

Aside from ensuring your tables are propery indexed you can replace your IN subqueries with INNER JOIN, and your NOT IN subqueries WITH LEFT JOIN/IS NULL, this should improve the performance:
INSERT INTO `goods` (`goods_id`, `price`, `name`)
SELECT `sales_goods`.`goods_id`,
`sales_goods`.`price`,
`sales_goods`.`goods_id`
FROM `sales_goods`
INNER JOIN
( SELECT MAX(`sales_goods`.`sales_goods_id`)
FROM `sales_goods`
LEFT JOIN `goods`
ON `goods`.`goods_id` = `sales_goods`.`goods_id`
WHERE `goods`.`goods_id` IS NULL
GROUP BY `sales_goods`.`goods_id`
) MaxSalesGoods
ON MaxSalesGoods.sales_goods_id = `sales_goods`.`sales_goods_id`

Related

Insert into multiple selects from different tables

I have tables users (id, email), permissions (id, description) and users_permissions (user_id, permission_id, created) with many to many relation.
I need to select user with some email and assign to him all permissions from table permissions, which he does not have.
Now I am trying to assign at least all permissions, but I am getting error
Subquery returns more than 1 row
My query:
insert into `users_permissions` (`user_id`, `permission_id`, `created`)
select
(select `id` from `users` where `email` = 'user-abuser#gmail.com') as `user_id`,
(select `id` from `permissions`) as `permission_id`,
now() as `created`;
If a subquery (inside SELECT) returns more than one row, MySQL does not like it.
Another way to achieve your requirement is using CROSS JOIN between Derived Tables (subquery in the FROM clause):
INSERT INTO `users_permissions` (`user_id`, `permission_id`, `created`)
SELECT
u.id,
p.id,
NOW()
FROM
users AS u
CROSS JOIN permissions AS p
WHERE u.email = 'user-abuser#gmail.com'

SQL Where Not Exists not working

I have two tables called TEMPDATA and Product. I am dumping all my data from a csv feed into TEMPDATA and then organising it into the respective tables, Product being one of them.
I am trying to insert all the contents of TEMPDATA that does not have a duplicate 'ean' number into Product, providing it doesn't already exist in Product.
The query I am trying to use is below...
INSERT IGNORE INTO `Product` (`product_ean`, `product_name`, `product_description`, `product_image`, `product_thumbnail`, `product_category`)
SELECT `ean`, `product_name`, `description`, `merchant_image_url`, `aw_thumb_url`, `merchant_category`
FROM (
SELECT `ean`, `product_name`, `description`, `merchant_image_url`, `aw_thumb_url`, `merchant_category`, count( * )
FROM TEMPDATA
GROUP BY `ean`
HAVING count( * ) = 1
) AS t
WHERE NOT EXISTS (
SELECT `product_ean` FROM Product
)
All the individual sections seem to be working, except from when I include the 'WHERE NOT EXISTS' clause, could someone please help me out?
try this:
INSERT IGNORE INTO Product (product_ean, product_name, product_description, product_image, product_thumbnail, product_category)
SELECT ean, product_name, description, merchant_image_url, aw_thumb_url, merchant_category
FROM (
SELECT ean, product_name, description, merchant_image_url, aw_thumb_url, merchant_category, count( * )
FROM TEMPDATA
GROUP BY ean
HAVING count( * ) = 1
) AS t
WHERE NOT EXISTS (
SELECT product_ean FROM Product AS A WHERE A.product_ean = t.product_name
)
you were missing this:
WHERE A.product_ean = t.product_name
in the NOT EXIST statement
you need to make you include the the where clause to search, see below
INSERT IGNORE INTO `Product` (`product_ean`, `product_name`, `product_description`, `product_image`, `product_thumbnail`, `product_category`)
SELECT `ean`, `product_name`, `description`, `merchant_image_url`, `aw_thumb_url`, `merchant_category`
FROM (
SELECT `ean`, `product_name`, `description`, `merchant_image_url`, `aw_thumb_url`, `merchant_category`, count( * )
FROM TEMPDATA
GROUP BY `ean`
HAVING count( * ) = 1
) AS t
WHERE NOT EXISTS (
SELECT `product_ean` FROM Product P where t.ean = p.`product_ean`
)

MySQL Select from UNION performance issue (kills database)

I have a little problem regarding MySQL
I'm trying to make a UNION of two tables like so:
SELECT `user_id`, `post_id`, `requested_on`
FROM `a`
WHERE `status` != 'cancelled'
UNION
SELECT `user_id`, `post_id`, `time` as requested_on
FROM `b`
WHERE `type` = 'ADD'
This query is executed in Showing rows 0 - 29 (36684 total, Query took 0.0147 sec)
but when I do
SELECT * FROM (
SELECT `user_id`, `post_id`, `requested_on`
FROM `a`
WHERE `status` != 'cancelled'
UNION
SELECT `user_id`, `post_id`, `time` as requested_on
FROM `b`
WHERE `type` = 'ADD'
) tbl1
MySQL dies.
The reason why I want to do this is to GROUP BY user_id, post_id
Any ideas why this happens / any workarounds?
later-edit:
This is the SQL Fiddle:
http://sqlfiddle.com/#!2/c7f82d/2
The final query is there, which executes in:
Record Count: 10; Execution Time: 574ms
574ms for 10 records in my point of view is gigantic.
I found what the problem was from.
It was the fact that I was running the queries in PHPMyAdmin and when I did a SELECT UNION SELECT everything was good but when I did
SELECT * FROM (SELECT UNION SELECT)
the pagination system from PHPMyAdmin failed, and PHPMyAdmin was trying to output to my browser a over 30k rows table, that's why the SQL Request hang. :(
It is not clear what the question:
SELECT * FROM (
SELECT user_id, post_id, requested_on
FROM a
WHERE status != cancelled
UNION
SELECT user_id, post_id, time as requested_on
FROM b
WHERE type = ADD
) tbl1 GROUP BY user_id, post_id
means. Assume you have:
A, x, t1
A, x, t2
would you like the row with t1 or t2? If that does not matter lets apply an aggregate function such as MIN:
SELECT user_id, post_id, MIN(requested_on) FROM (
SELECT user_id, post_id, requested_on
FROM a
WHERE status <> cancelled
UNION
SELECT user_id, post_id, time as requested_on
FROM b
WHERE type = ADD
) tbl1
GROUP BY user_id, post_id
MySQL usually doesn't handle derived tables like this very well, is there any other predicate that you can apply to the parts in the union?

SQL command doesn't return rows

I have a SQL command which I know data exists with the criteria, but when I run the query it doesn't return rows:
SQL:
SELECT `USER_ID`, `CAR_ID`, `AD_ID`, `BRAND`, `MODEL`
, `YEAR`, `PRICE`, `MILEAGE`, `GEARBOX`, `STATUS`, `COLOR_IN`, `COLOR_OUT`
, `BODY`, `FUEL`, `ABOUT`, `MAIN_PHOTO`
FROM (`ads`, `cars`, `ad_extras`)
WHERE `ads`.`USER_ID` = '2'
What should I do?
EDIT:
When I do SELECT * it also doesn't return data.
when I select from 2 tables it retaurns data. So I can't select from 3 tables right?
It's likeky that one of your tables is empty. The result of that is empty.You should use a query like this one
SELECT `USER_ID`, `CAR_ID`, `AD_ID`, `BRAND`, `MODEL`, `YEAR`, `PRICE`, `MILEAGE`, `GEARBOX`, `STATUS`, `COLOR_IN`, `COLOR_OUT`, `BODY`, `FUEL`, `ABOUT`, `MAIN_PHOTO` FROM `ads` natural left join `cars` natural left join `ad_extras` WHERE `ads`.`USER_ID` = '2'
I wanted to post this like a comment but I don't have enought privilegies.
In order to query from 3 table it is better to use JOIN clause between them
or if you want to write it as it is use alias for selecting columns
e.g
SELECT 'ads.USER_ID', 'cars.CAR_ID', 'ads.AD_ID'
FROM ('ads', 'cars', 'ad_extras')
WHERE 'ads'.'USER_ID' = '2'
with their respective table

INSERT query with subquery: Column count doesn't match value count at row 1

I have this query that inserts rows, using a subquery like so:
INSERT INTO Lecture_presence_Student (`presence_id`, `Lecture_id`, `Student_id`, `status`) VALUES
(
(
SELECT '' as presence_id, Lecture.Lecture_id, CourseEdition_students_Student.Student_id, 'onverwerkt'
FROM
CourseEdition_students_Student
INNER JOIN Lecture ON CourseEdition_students_Student.CourseEdition_id = Lecture.CourseEdition_id
)
)
I don't get it, the sub select query returns 4 columns, the same number as the INSERT query. Why does it give me the error:
Column count doesn't match value count at row 1
Any ideas?
instead of using INSERT INTO VALUES, use INSERT INTO SELECT FROM
INSERT INTO Lecture_presence_Student
(
`presence_id`
, `Lecture_id`
, `Student_id`
, `status`
)
SELECT '' as presence_id
, Lecture.Lecture_id
, CourseEdition_students_Student.Student_id
, 'onverwerkt'
FROM CourseEdition_students_Student
INNER JOIN Lecture
ON CourseEdition_students_Student.CourseEdition_id = Lecture.CourseEdition_id
then if you get more than one record in your query, the INSERT will work.
INSERT INTO Lecture_presence_Student (`presence_id`, `Lecture_id`, `Student_id`, `status`)
SELECT '' as presence_id, Lecture.Lecture_id, CourseEdition_students_Student.Student_id, 'onverwerkt'
FROM
CourseEdition_students_Student
INNER JOIN Lecture ON CourseEdition_students_Student.CourseEdition_id = Lecture.CourseEdition_id
and what for empty value for presence_id?
INSERT INTO Lecture_presence_Student (`presence_id`, `Lecture_id`, `Student_id`, `status`)
SELECT '', Lecture.Lecture_id, CourseEdition_students_Student.Student_id, 'onverwerkt'
FROM
CourseEdition_students_Student
INNER JOIN Lecture ON CourseEdition_students_Student.CourseEdition_id = Lecture.CourseEdition_id
Remove your "VALUES(())" and the alias won't be necessary.