mysql join 3 table retain order of data order by used in subquery
I have a query like this
SELECT a.pmid,a.sendid,a.sendtime,a.recid,a.message,b.unread,r.avator1 ra,s.avator1 sa,s.username sun,r.username run
FROM pm a
JOIN
(
SELECT SUM(IF(recid = '347' and hasread=0, 1, 0)) AS undread,
LEAST(sendid,recid) user1 ,
GREATEST(sendid,recid) user2 ,
MAX(pmid) pmid
FROM pm
WHERE sendid='347' OR recid='347'
GROUP BY user1 , user2
) b
ON b.pmid = a.pmid
JOIN
users s ON s.userid = a.sendid
JOIN
users r ON r.userid=a.recid
ORDER BY unread DESC, pmid DESC LIMIT 0,10
I have performance issue with this query it's taking some 8-10 seconds to complete execution if I alter by removing order by unread desc
from the past of the query
query complete execution with in 1 sec but result is wrong,not what i need.
if i move order by unread desc
inside the subquery example
SELECT a.pmid,
a.sendid,
a.sendtime,
a.recid,
a.message,
b.unread,
r.avator1 ra,
s.avator1 sa,
s.username sun,
r.username run
FROM pm a
JOIN
(SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,pmid DESC) b ON b.pmid = a.pmid
JOIN users s ON s.userid=a.sendid
JOIN users r ON r.userid=a.recid
LIMIT 0,
10
then it is still not giving result what i need.
if i run the subquery ``
SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,
pmid DESC
separately then its giving correct data but then if i join user table once with on either recid or sendid then result is correct but when i join user table twice with both sendid and recid then the result order is incorrect.
table pm
structure here
CREATE TABLE `pm` (
`pmid` bigint(40) unsigned NOT NULL AUTO_INCREMENT,
`sendid` bigint(20) unsigned DEFAULT NULL,
`recid` bigint(20) unsigned DEFAULT NULL,
`subject` mediumtext DEFAULT NULL,
`message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`hasread` int(10) unsigned DEFAULT 0,
`sendtime` int(10) unsigned DEFAULT NULL,
`ack` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`pmid`),
KEY `sendid_2` (`sendid`,`recid`),
KEY `recid` (`recid`,`hasread`),
KEY `recid_2` (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1900982 DEFAULT CHARSET=utf8
table users
structure here
CREATE TABLE `users` (
`userid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
`username` text CHARACTER SET latin1 DEFAULT NULL,
`password` text CHARACTER SET latin1 DEFAULT NULL,
`pass` varchar(30) CHARACTER SET latin1 NOT NULL,
`groupid` bigint(20) unsigned NOT NULL DEFAULT 2,
`email` text CHARACTER SET latin1 DEFAULT NULL,
`rank` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0',
`validated` int(10) unsigned NOT NULL DEFAULT 0,
`avator1` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0.gif',
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=33744 DEFAULT CHARSET=utf8mb4
please help me.
mysql
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
|
show 1 more comment
I have a query like this
SELECT a.pmid,a.sendid,a.sendtime,a.recid,a.message,b.unread,r.avator1 ra,s.avator1 sa,s.username sun,r.username run
FROM pm a
JOIN
(
SELECT SUM(IF(recid = '347' and hasread=0, 1, 0)) AS undread,
LEAST(sendid,recid) user1 ,
GREATEST(sendid,recid) user2 ,
MAX(pmid) pmid
FROM pm
WHERE sendid='347' OR recid='347'
GROUP BY user1 , user2
) b
ON b.pmid = a.pmid
JOIN
users s ON s.userid = a.sendid
JOIN
users r ON r.userid=a.recid
ORDER BY unread DESC, pmid DESC LIMIT 0,10
I have performance issue with this query it's taking some 8-10 seconds to complete execution if I alter by removing order by unread desc
from the past of the query
query complete execution with in 1 sec but result is wrong,not what i need.
if i move order by unread desc
inside the subquery example
SELECT a.pmid,
a.sendid,
a.sendtime,
a.recid,
a.message,
b.unread,
r.avator1 ra,
s.avator1 sa,
s.username sun,
r.username run
FROM pm a
JOIN
(SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,pmid DESC) b ON b.pmid = a.pmid
JOIN users s ON s.userid=a.sendid
JOIN users r ON r.userid=a.recid
LIMIT 0,
10
then it is still not giving result what i need.
if i run the subquery ``
SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,
pmid DESC
separately then its giving correct data but then if i join user table once with on either recid or sendid then result is correct but when i join user table twice with both sendid and recid then the result order is incorrect.
table pm
structure here
CREATE TABLE `pm` (
`pmid` bigint(40) unsigned NOT NULL AUTO_INCREMENT,
`sendid` bigint(20) unsigned DEFAULT NULL,
`recid` bigint(20) unsigned DEFAULT NULL,
`subject` mediumtext DEFAULT NULL,
`message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`hasread` int(10) unsigned DEFAULT 0,
`sendtime` int(10) unsigned DEFAULT NULL,
`ack` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`pmid`),
KEY `sendid_2` (`sendid`,`recid`),
KEY `recid` (`recid`,`hasread`),
KEY `recid_2` (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1900982 DEFAULT CHARSET=utf8
table users
structure here
CREATE TABLE `users` (
`userid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
`username` text CHARACTER SET latin1 DEFAULT NULL,
`password` text CHARACTER SET latin1 DEFAULT NULL,
`pass` varchar(30) CHARACTER SET latin1 NOT NULL,
`groupid` bigint(20) unsigned NOT NULL DEFAULT 2,
`email` text CHARACTER SET latin1 DEFAULT NULL,
`rank` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0',
`validated` int(10) unsigned NOT NULL DEFAULT 0,
`avator1` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0.gif',
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=33744 DEFAULT CHARSET=utf8mb4
please help me.
mysql
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output ofSHOW CREATE TABLE my_tableG
for all the tables in your query?
– Vérace
Sep 23 '17 at 8:24
edited my dear.
– panchayat
Sep 23 '17 at 8:49
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
edited again...
– panchayat
Sep 23 '17 at 9:04
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDLCREATE...
), data (in the form of DML -INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!
– Vérace
Sep 23 '17 at 11:50
|
show 1 more comment
I have a query like this
SELECT a.pmid,a.sendid,a.sendtime,a.recid,a.message,b.unread,r.avator1 ra,s.avator1 sa,s.username sun,r.username run
FROM pm a
JOIN
(
SELECT SUM(IF(recid = '347' and hasread=0, 1, 0)) AS undread,
LEAST(sendid,recid) user1 ,
GREATEST(sendid,recid) user2 ,
MAX(pmid) pmid
FROM pm
WHERE sendid='347' OR recid='347'
GROUP BY user1 , user2
) b
ON b.pmid = a.pmid
JOIN
users s ON s.userid = a.sendid
JOIN
users r ON r.userid=a.recid
ORDER BY unread DESC, pmid DESC LIMIT 0,10
I have performance issue with this query it's taking some 8-10 seconds to complete execution if I alter by removing order by unread desc
from the past of the query
query complete execution with in 1 sec but result is wrong,not what i need.
if i move order by unread desc
inside the subquery example
SELECT a.pmid,
a.sendid,
a.sendtime,
a.recid,
a.message,
b.unread,
r.avator1 ra,
s.avator1 sa,
s.username sun,
r.username run
FROM pm a
JOIN
(SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,pmid DESC) b ON b.pmid = a.pmid
JOIN users s ON s.userid=a.sendid
JOIN users r ON r.userid=a.recid
LIMIT 0,
10
then it is still not giving result what i need.
if i run the subquery ``
SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,
pmid DESC
separately then its giving correct data but then if i join user table once with on either recid or sendid then result is correct but when i join user table twice with both sendid and recid then the result order is incorrect.
table pm
structure here
CREATE TABLE `pm` (
`pmid` bigint(40) unsigned NOT NULL AUTO_INCREMENT,
`sendid` bigint(20) unsigned DEFAULT NULL,
`recid` bigint(20) unsigned DEFAULT NULL,
`subject` mediumtext DEFAULT NULL,
`message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`hasread` int(10) unsigned DEFAULT 0,
`sendtime` int(10) unsigned DEFAULT NULL,
`ack` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`pmid`),
KEY `sendid_2` (`sendid`,`recid`),
KEY `recid` (`recid`,`hasread`),
KEY `recid_2` (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1900982 DEFAULT CHARSET=utf8
table users
structure here
CREATE TABLE `users` (
`userid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
`username` text CHARACTER SET latin1 DEFAULT NULL,
`password` text CHARACTER SET latin1 DEFAULT NULL,
`pass` varchar(30) CHARACTER SET latin1 NOT NULL,
`groupid` bigint(20) unsigned NOT NULL DEFAULT 2,
`email` text CHARACTER SET latin1 DEFAULT NULL,
`rank` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0',
`validated` int(10) unsigned NOT NULL DEFAULT 0,
`avator1` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0.gif',
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=33744 DEFAULT CHARSET=utf8mb4
please help me.
mysql
I have a query like this
SELECT a.pmid,a.sendid,a.sendtime,a.recid,a.message,b.unread,r.avator1 ra,s.avator1 sa,s.username sun,r.username run
FROM pm a
JOIN
(
SELECT SUM(IF(recid = '347' and hasread=0, 1, 0)) AS undread,
LEAST(sendid,recid) user1 ,
GREATEST(sendid,recid) user2 ,
MAX(pmid) pmid
FROM pm
WHERE sendid='347' OR recid='347'
GROUP BY user1 , user2
) b
ON b.pmid = a.pmid
JOIN
users s ON s.userid = a.sendid
JOIN
users r ON r.userid=a.recid
ORDER BY unread DESC, pmid DESC LIMIT 0,10
I have performance issue with this query it's taking some 8-10 seconds to complete execution if I alter by removing order by unread desc
from the past of the query
query complete execution with in 1 sec but result is wrong,not what i need.
if i move order by unread desc
inside the subquery example
SELECT a.pmid,
a.sendid,
a.sendtime,
a.recid,
a.message,
b.unread,
r.avator1 ra,
s.avator1 sa,
s.username sun,
r.username run
FROM pm a
JOIN
(SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,pmid DESC) b ON b.pmid = a.pmid
JOIN users s ON s.userid=a.sendid
JOIN users r ON r.userid=a.recid
LIMIT 0,
10
then it is still not giving result what i need.
if i run the subquery ``
SELECT SUM(IF(recid = '347'
AND hasread=0, 1, 0)) AS unread,
LEAST(sendid,recid) user1,
GREATEST(sendid,recid) user2,
MAX(pmid) pmid
FROM pm
WHERE sendid='347'
OR recid='347'
GROUP BY user1,
user2
ORDER BY unread DESC,
pmid DESC
separately then its giving correct data but then if i join user table once with on either recid or sendid then result is correct but when i join user table twice with both sendid and recid then the result order is incorrect.
table pm
structure here
CREATE TABLE `pm` (
`pmid` bigint(40) unsigned NOT NULL AUTO_INCREMENT,
`sendid` bigint(20) unsigned DEFAULT NULL,
`recid` bigint(20) unsigned DEFAULT NULL,
`subject` mediumtext DEFAULT NULL,
`message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`hasread` int(10) unsigned DEFAULT 0,
`sendtime` int(10) unsigned DEFAULT NULL,
`ack` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`pmid`),
KEY `sendid_2` (`sendid`,`recid`),
KEY `recid` (`recid`,`hasread`),
KEY `recid_2` (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1900982 DEFAULT CHARSET=utf8
table users
structure here
CREATE TABLE `users` (
`userid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
`username` text CHARACTER SET latin1 DEFAULT NULL,
`password` text CHARACTER SET latin1 DEFAULT NULL,
`pass` varchar(30) CHARACTER SET latin1 NOT NULL,
`groupid` bigint(20) unsigned NOT NULL DEFAULT 2,
`email` text CHARACTER SET latin1 DEFAULT NULL,
`rank` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0',
`validated` int(10) unsigned NOT NULL DEFAULT 0,
`avator1` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '0.gif',
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=33744 DEFAULT CHARSET=utf8mb4
please help me.
mysql
mysql
edited Sep 23 '17 at 9:03
panchayat
asked Sep 23 '17 at 6:41
panchayatpanchayat
1114
1114
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output ofSHOW CREATE TABLE my_tableG
for all the tables in your query?
– Vérace
Sep 23 '17 at 8:24
edited my dear.
– panchayat
Sep 23 '17 at 8:49
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
edited again...
– panchayat
Sep 23 '17 at 9:04
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDLCREATE...
), data (in the form of DML -INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!
– Vérace
Sep 23 '17 at 11:50
|
show 1 more comment
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output ofSHOW CREATE TABLE my_tableG
for all the tables in your query?
– Vérace
Sep 23 '17 at 8:24
edited my dear.
– panchayat
Sep 23 '17 at 8:49
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
edited again...
– panchayat
Sep 23 '17 at 9:04
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDLCREATE...
), data (in the form of DML -INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!
– Vérace
Sep 23 '17 at 11:50
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output of
SHOW CREATE TABLE my_tableG
for all the tables in your query?– Vérace
Sep 23 '17 at 8:24
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output of
SHOW CREATE TABLE my_tableG
for all the tables in your query?– Vérace
Sep 23 '17 at 8:24
edited my dear.
– panchayat
Sep 23 '17 at 8:49
edited my dear.
– panchayat
Sep 23 '17 at 8:49
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
edited again...
– panchayat
Sep 23 '17 at 9:04
edited again...
– panchayat
Sep 23 '17 at 9:04
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDL
CREATE...
), data (in the form of DML - INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!– Vérace
Sep 23 '17 at 11:50
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDL
CREATE...
), data (in the form of DML - INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!– Vérace
Sep 23 '17 at 11:50
|
show 1 more comment
1 Answer
1
active
oldest
votes
This kludge allegedly works: Tack LIMIT 999999999
onto the subquery. That forces the optimizer to use the ORDER BY
. Normally (in newer versions of MySQL), the Optimizer simply throws away the ORDER BY
in certain subqueries -- because the SQL Standard says that a subquery delivers an unordered set. A reference.
(Not relevant in your case.) Meanwhile, explicitly add ORDER BY
in the subquery; don't depend on GROUP BY
providing an ordering. That MySQL 'extension' is in flux. (If the GROUP BY
and ORDER BY
are the same, the Optimizer is smart enough to do them together.)
Because of the OR
, the only practical way to do the subquery is with a full table scan of the 2M rows.
Optimization tip: Smaller --> faster, especially if the table is too big to be cached. So...
- Don't use
BIGINT
(8 bytes) when something smaller would suffice. - Don't use
INT
(4 bytes) for a 'flag'.TINYINT
is 1 byte. - Don't use
TEXT
whenVARCHAR(255 or less)
would suffice. (There is an extra savings when a tmp table is needed.)
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f186721%2fmysql-join-3-table-retain-order-of-data-order-by-used-in-subquery%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This kludge allegedly works: Tack LIMIT 999999999
onto the subquery. That forces the optimizer to use the ORDER BY
. Normally (in newer versions of MySQL), the Optimizer simply throws away the ORDER BY
in certain subqueries -- because the SQL Standard says that a subquery delivers an unordered set. A reference.
(Not relevant in your case.) Meanwhile, explicitly add ORDER BY
in the subquery; don't depend on GROUP BY
providing an ordering. That MySQL 'extension' is in flux. (If the GROUP BY
and ORDER BY
are the same, the Optimizer is smart enough to do them together.)
Because of the OR
, the only practical way to do the subquery is with a full table scan of the 2M rows.
Optimization tip: Smaller --> faster, especially if the table is too big to be cached. So...
- Don't use
BIGINT
(8 bytes) when something smaller would suffice. - Don't use
INT
(4 bytes) for a 'flag'.TINYINT
is 1 byte. - Don't use
TEXT
whenVARCHAR(255 or less)
would suffice. (There is an extra savings when a tmp table is needed.)
add a comment |
This kludge allegedly works: Tack LIMIT 999999999
onto the subquery. That forces the optimizer to use the ORDER BY
. Normally (in newer versions of MySQL), the Optimizer simply throws away the ORDER BY
in certain subqueries -- because the SQL Standard says that a subquery delivers an unordered set. A reference.
(Not relevant in your case.) Meanwhile, explicitly add ORDER BY
in the subquery; don't depend on GROUP BY
providing an ordering. That MySQL 'extension' is in flux. (If the GROUP BY
and ORDER BY
are the same, the Optimizer is smart enough to do them together.)
Because of the OR
, the only practical way to do the subquery is with a full table scan of the 2M rows.
Optimization tip: Smaller --> faster, especially if the table is too big to be cached. So...
- Don't use
BIGINT
(8 bytes) when something smaller would suffice. - Don't use
INT
(4 bytes) for a 'flag'.TINYINT
is 1 byte. - Don't use
TEXT
whenVARCHAR(255 or less)
would suffice. (There is an extra savings when a tmp table is needed.)
add a comment |
This kludge allegedly works: Tack LIMIT 999999999
onto the subquery. That forces the optimizer to use the ORDER BY
. Normally (in newer versions of MySQL), the Optimizer simply throws away the ORDER BY
in certain subqueries -- because the SQL Standard says that a subquery delivers an unordered set. A reference.
(Not relevant in your case.) Meanwhile, explicitly add ORDER BY
in the subquery; don't depend on GROUP BY
providing an ordering. That MySQL 'extension' is in flux. (If the GROUP BY
and ORDER BY
are the same, the Optimizer is smart enough to do them together.)
Because of the OR
, the only practical way to do the subquery is with a full table scan of the 2M rows.
Optimization tip: Smaller --> faster, especially if the table is too big to be cached. So...
- Don't use
BIGINT
(8 bytes) when something smaller would suffice. - Don't use
INT
(4 bytes) for a 'flag'.TINYINT
is 1 byte. - Don't use
TEXT
whenVARCHAR(255 or less)
would suffice. (There is an extra savings when a tmp table is needed.)
This kludge allegedly works: Tack LIMIT 999999999
onto the subquery. That forces the optimizer to use the ORDER BY
. Normally (in newer versions of MySQL), the Optimizer simply throws away the ORDER BY
in certain subqueries -- because the SQL Standard says that a subquery delivers an unordered set. A reference.
(Not relevant in your case.) Meanwhile, explicitly add ORDER BY
in the subquery; don't depend on GROUP BY
providing an ordering. That MySQL 'extension' is in flux. (If the GROUP BY
and ORDER BY
are the same, the Optimizer is smart enough to do them together.)
Because of the OR
, the only practical way to do the subquery is with a full table scan of the 2M rows.
Optimization tip: Smaller --> faster, especially if the table is too big to be cached. So...
- Don't use
BIGINT
(8 bytes) when something smaller would suffice. - Don't use
INT
(4 bytes) for a 'flag'.TINYINT
is 1 byte. - Don't use
TEXT
whenVARCHAR(255 or less)
would suffice. (There is an extra savings when a tmp table is needed.)
answered Sep 23 '17 at 14:36
Rick JamesRick James
43k22259
43k22259
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f186721%2fmysql-join-3-table-retain-order-of-data-order-by-used-in-subquery%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Could you edit your question's queries (I did the first one) so that they're consistent and legible. You'll get more and better help that way! Also, could you provide the output of
SHOW CREATE TABLE my_tableG
for all the tables in your query?– Vérace
Sep 23 '17 at 8:24
edited my dear.
– panchayat
Sep 23 '17 at 8:49
And the structure of users?
– Vérace
Sep 23 '17 at 8:58
edited again...
– panchayat
Sep 23 '17 at 9:04
Also, some sample data would be great - provided it's not sensitive! Ideally, when asking a question, give the tables (in the form of DDL
CREATE...
), data (in the form of DML -INSERT...
), your desired output and the logic you are using to obtain that output. Any further information, such as failed attempts &c. is also beneficial. These sites are a great resource - you will get all the more out of them if you can give us everything we could need to help you! p.s. welcome to the forum!– Vérace
Sep 23 '17 at 11:50