Simple MySQL INSERT query very slow - mysql

I think I'm having an issue with my MySQL server or the Query I'm using. I'm not sure which.
Server is VM Ubuntu12.4 4 cores/16gb Ram
MySQL 5.5.24 x86
My query:
INSERT INTO `NEWTEXT`.`Order_LineDetails`
( OrderLineItem_ID, Customer_ID, Order_ID, ProductName )
SELECT
'Order_Details'.'OrderDetailID',
'Orders'.'CustomerID',
'Order_Details'.'OrderID',
'prods'.'ProductName'
FROM Order_Details
JOIN Orders ON Orders.OrderID = Order_Details.OrderID
JOIN Products prods ON prods.ProductID = Order_Details.ProductID
WHERE Orders.OrderID = 500000
I'm not really sure where to start looking for the problem. The above query takes 9+ seconds to complete. The Order_Details table contains 1,800,000+ records in it.
The thing that is bugging me on this is that when I run a select query it also goes slow. BUT, I have another server that's running win2k MsSql and its almost instant with the same SELECT query.
I'm hoping someone could point me in the right direction here.
EDIT
Well, sorry for the troubles and thanks for your help.
I found that the problem was that after I finished the import I skipped the step where I would normally assign the new tables a PrimaryKey. I know, :( dumb.
Anyway! Don't forget to assign your Primary Keys!

Back to the start:
http://dev.mysql.com/doc/refman/5.5/en/optimizing-primary-keys.html

Related

Why this simple subquery gets wrong results?

I have table with documents nammed: z_web_dok it has 133,369 rows, the other table with products nammed: z_web_dok_art has 693,930 rows, all fields needed for querying are indexed, and connection between those tables is auto increment field of z_web_dok.oid and z_web_dok_art.oid_id.
What is the problem?
I were made simple sql query for returning old prices (by buyer, place, country). The query is:
SELECT (COALESCE(NULLIF(TNew.cijena_e,''), TNew.cijena)*(TN.kurs_iznos/1))
FROM z_web_dok_art As TNew
INNER JOIN z_web_dok As TN ON TN.oid=TNew.oid_id
WHERE (TN.Drzava='BiH' AND TNew.aid='SOME_PRODUCT_ID' AND TN.vrsta_dok='pri'
AND TN.kup_id='1047' AND TN.mag_id='5' AND TN.oid<>'151967')
ORDER BY TN.dat_zavrsena DESC
LIMIT 1
and it worked, for each product, so i used it inside another query, which gets products their new prices and with the query above (subquery) i tried to pull the old prices (Connection was between tables: TNew.aid=WArt.aid )
SELECT WArt.aid, WArt.nc, WArt.isp, COALESCE(NULLIF(WArt.cijena_e,''), WArt.cijena) As cijena, WArt.rab, WArt.vpc, WArt.mpc, C.EAN, C.Model, C.Naziv, C.JM, C.WebBiH, C.DostupnostBiH,
(
SELECT (COALESCE(NULLIF(TNew.cijena_e,''), TNew.cijena)*(TN.kurs_iznos/1))
FROM z_web_dok_art As TNew
INNER JOIN z_web_dok As TN ON TN.oid=TNew.oid_id
WHERE (TN.Drzava='BiH' AND TNew.aid=WArt.aid AND TN.vrsta_dok='pri'
AND TN.kup_id='1047' AND TN.mag_id='5' AND TN.oid<>'151967')
ORDER BY TN.dat_zavrsena DESC
LIMIT 1
) As s_cijena
FROM
z_web_dok_art As WArt
LEFT JOIN Cjenovnik As C ON C.ID=WArt.aid
WHERE WArt.oid_id='151967'
ORDER BY CASE WHEN WArt.isp='0' THEN 1 ELSE 0 END, WArt.id_dok_art
It worked, for a long period, but today we discovered it returned 6 times higher result for old price for two products (on a order that has 19 products).
So i were query TN.oid with same query to see what does it pulls from database and it was oid that has following fields same: (kup_id, vrsta_dok) but all others are different even if the query asked for Drzava='BiH' AND TN.mag_id='5' it doesn't return results for that.
But the other problem is, if i execute subquery as query alone, with that product (or more them) it returns RIGHT RESULTS. But above one mixed results right and wrong one.
It's not problem in solving this!
I can solve it, but i wanted to know why this QUERY didn't work, i mean, what's the problem with it? Did anyone had problem with this?
This is my first bad experience with similar queries...
I were thinking about, it's happening because of subquery JOINS with another table inside of query (because the subquery works perfect without it's parent query).
Thank you for your time!
Best regards,
Nedžad.
IMPORTANT UPDATE (25.10.2016):
The server mysql version: 5.5.52-cll
Local version mysql: 5.6.17 - MySQL Community Server (GPL)
Localhost returned the proper results, with NO MISTAKE,
while the server mysql still returns wrong results..
Is it bug at mysql 5.5.52-cll or what?
Image of results:
UPDATE: (SOLVED)
And i solved it by using group in subquery:
GROUP BY TNew.oid_id, TNew.aid
(grouping by, documents, and products inside of it), and it returned the right results - the performance was good, 0.1704 (which is good because it's always one document at opening). Once again, thanks everyone which were lead me to right path

MS Access 2010: Query time and speed

I am running the following insert query in MS Access 2010, and I need a way for the query to run faster. I do need to get all of the columns from the Source_1_table into the temp_Table.
Source_1_table has 505K records
Source_2_table has 3959 records
INSERT INTO [temp_Table]
SELECT *
FROM Source_1_table
WHERE
((dbo_Source_1_table.Field_1)) Not IN (SELECT [Source_2_table].[ID_Field] FROM [Source_2_table]));
Question 1. How do I see how long it is taking the query to run (similar to SSMS)?
Question 2. The query seems to be taking longer than 10 minutes to run. Is there any way speed up this query?
I've never worked with that many records in an Access db before, so I'm not surprised it's slow.
I solved a similar problem recently in some legacy code. I think a big problem is that you are running your subquery once for every record in the main query (someone please correct me if that's not correct). Try this instead:
INSERT INTO [temp_Table]
SELECT s1.*
FROM Source_1_table s1
Left Join Source_1_table s2 on s1.Field_1=s2.ID_Field
where s2.ID_Field is null

Mysql - Showing the 1 latest entry from each unique field

I fail at mysql, and could really do with some help. I don't know what it would be called, and all my attempts at using combinations of DISTINCT and GROUP BY are just not working out.
I have a table of server monitoring data with these columns:
nStatusNumber
Bandwidth
Load
Users
ServerNumber
DiskFree
MemFree
TimeStamp
**nStatusNumber** - A unique number increasing for each entry
**ServerNumber** - A unique number for each server
For the top of my dashboard for this, I need to display the most recent report for each unique server.
// How many servers are we monitoring ?
$nNumServers = mysql_numrows(mysql_query("SELECT DISTINCT(ServerNumber) FROM server_status;"));
// Get our list of servers
$strQuery = "SELECT * FROM server_status ORDER BY nStatusNumber DESC limit ".$nNumServers.";";
And then loop through the results until we hit $nNumServers . This worked at first, until servers started going down/up and the report order got jumbled.
Say theres 20 servers, the most recent 20 results aren't necessarily 1 from each server.
I'm trying to figure this out in a hurry, and failing at it. I've tried all sorts of combinations of DISTINCT and GROUP BY with no luck so far and would appreciate any guidance on what's probably an embarrassingly easy problem that I just can't see the answer to.
Thanks!
PS - Here's an example query that I've been trying, showing the problem I'm having. Check the "nStatusNumber" field, these should be showing the most recent results only for each server - http://pastebin.com/raw.php?i=ngXLRhd6
PPS - Setting max(nStatusNumber) doesn't give accurate results. I don't want some average/sum/median figure, I need the most recent ACTUAL figures reported by each server. Heres more example results for the queries:
http://pastebin.com/raw.php?i=eyuPD7vj
For your purpose you need to find the row unique to a nServerNumber and TimeStamp. This is not as simple as just saying MAX(TimeStamp) as you need to find the row corresponding to it.
Although I am not an expert in SQL you can try this and see if it works.
SELECT A.nServerNumber, A.nStatusNumber, A.nVNStatsBandwidth, A.fLoad, A.nUsers,
A.nUsersPaid, A.nServerNumber, A.nFreeDisk, A.nTotalDisk, A.nFreeMemory,
A.nTotalMemory, A.TimeStamp
FROM server_status A
INNER JOIN
(
SELECT nServerNumber, MAX(TimeStamp) as `TimeStamp`
FROM server_status
GROUP BY nServerNumber
) B
ON A.nServerNumber = B.nServerNumber
AND A.TimeStamp = B.TimeStamp
ORDER BY A.nServerNumber ASC;
This query will give you all the servers with their latest info. So if you want the total number of servers just run the mysql_numrows(...) function on this result and if you want the data just iterate through the same result (no need to fire two separate SQL queries).
Try this ::
Select
Select MAX(nStatusNumber) from table,
Bandwidth,
Load,
Users,
ServerNumber,
DiskFree,
MemFree,
MAX(`TimeStamp`)
from your table
group by ServerNumber

MySQL Subquery Causing Server to Hang

I'm trying to execute the following query
SELECT * FROM person
WHERE id IN
( SELECT user_id FROM participation
WHERE activity_id = '1' AND application_id = '1'
)
The outer query returns about 4000 responses whilst the inner returns 29. When executed on my web server nothing happened and when I tested it locally mysql ended up using 100% CPU and still achieved nothing. Could the size be the cause?
Specifically it causes the server to hang forever, I'm fairly sure the web server I ran the query on is in the process of crashing due to it (woops).
why don't you use an inner join for this query? i think that would be faster (and easier to read) - and maybe it solves your problem (but i can't find a failure in your query).
EDIT: the inner-join-solution would look like this:
SELECT
person.*
FROM
person
INNER JOIN
participation
ON
person.id = participation.user_id
WHERE
participation.activity_id = '1'
AND
participation.application_id = '1'
How many rows are there in participation table and what indexes are there?
A multi-column index on (user_id, activity_id, application_id) could help here.
Re comments: IN isn't slow. Subqueries within IN can be slow, if they're correlated to outer query.

Slow query when using ORDER BY

Here's the query (the largest table has about 40,000 rows)
SELECT
Course.CourseID,
Course.Description,
UserCourse.UserID,
UserCourse.TimeAllowed,
UserCourse.CreatedOn,
UserCourse.PassedOn,
UserCourse.IssuedOn,
C.LessonCnt
FROM
UserCourse
INNER JOIN
Course
USING(CourseID)
INNER JOIN
(
SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
) C
USING(CourseID)
WHERE
UserCourse.UserID = 8810
If I run this, it executes very quickly (.05 seconds roughly). It returns 13 rows.
When I add an ORDER BY clause at the end of the query (ordering by any column) the query takes about 10 seconds.
I'm using this database in production now, and everything is working fine. All my other queries are speedy.
Any ideas of what it could be? I ran the query in MySQL's Query Browser, and from the command line. Both places it was dead slow with the ORDER BY.
EDIT: Tolgahan ALBAYRAK solution works, but can anyone explain why it works?
maybe this helps:
SELECT * FROM (
SELECT
Course.CourseID,
Course.Description,
UserCourse.UserID,
UserCourse.TimeAllowed,
UserCourse.CreatedOn,
UserCourse.PassedOn,
UserCourse.IssuedOn,
C.LessonCnt
FROM
UserCourse
INNER JOIN
Course
USING(CourseID)
INNER JOIN
(
SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
) C
USING(CourseID)
WHERE
UserCourse.UserID = 8810
) ORDER BY CourseID
Is the column you're ordering by indexed?
Indexing drastically speeds up ordering and filtering.
You are selecting from "UserCourse" which I assume is a joining table between courses and users (Many to Many).
You should index the column that you need to order by, in the "UserCourse" table.
Suppose you want to "order by CourseID", then you need to index it on UserCourse table.
Ordering by any other column that is not present in the joining table (i.e. UserCourse) may require further denormalization and indexing on the joining table to be optimized for speed;
In other words, you need to have a copy of that column in the joining table and index it.
P.S.
The answer given by Tolgahan Albayrak, although correct for this question, would not produce the desired result, in cases where one is doing a "LIMIT x" query.
Have you updated the statistics on your database? I ran into something similar on mine where I had 2 identical queries where the only difference was a capital letter and one returned in 1/2 a second and the other took nearly 5 minutes. Updating the statistics resolved the issue
Realise answer is too late, however I have just had a similar problem, adding order by increased the query time from seconds to 5 minutes and having tried most other suggestions for speeding it up, noticed that the /tmp files where getting to be 12G for this query. Changed the query such that a varchar(20000) field being returned was "trim("ed and performance dramatically improved (back to seconds). So I guess its worth checking whether you are returning large varchars as part of your query and if so, process them (maybe substring(x, 1, length(x))?? if you dont want to trim them.
Query was returning 500k rows and the /tmp file indicated that each row was using about 20k of data.
A similar question was asked before here.
It might help you as well. Basically it describes using composite indexes and how order by works.
Today I was running into a same kind of problem. As soon as I was sorting the resultset by a field from a joined table, the whole query was horribly slow and took more than a hundred seconds.
The server was running MySQL 5.0.51a and by chance I noticed that the same query was running as fast as it should have always done on a server with MySQL 5.1. When comparing the explains for that query I saw that obviously the usage and handling of indexes has changed a lot (at least from 5.0 -> 5.1).
So if you encounter such a problem, maybe your resolution is to simply upgrade your MySQL