mysql join 3 table retain order of data order by used in subquery












0















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.










share|improve this question
















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 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


















0















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.










share|improve this question
















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 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
















0












0








0








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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





















  • 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



















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












1 Answer
1






active

oldest

votes


















0














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 when VARCHAR(255 or less) would suffice. (There is an extra savings when a tmp table is needed.)






share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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 when VARCHAR(255 or less) would suffice. (There is an extra savings when a tmp table is needed.)






    share|improve this answer




























      0














      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 when VARCHAR(255 or less) would suffice. (There is an extra savings when a tmp table is needed.)






      share|improve this answer


























        0












        0








        0







        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 when VARCHAR(255 or less) would suffice. (There is an extra savings when a tmp table is needed.)






        share|improve this answer













        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 when VARCHAR(255 or less) would suffice. (There is an extra savings when a tmp table is needed.)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 23 '17 at 14:36









        Rick JamesRick James

        43k22259




        43k22259






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Liste der Baudenkmale in Friedland (Mecklenburg)

            Single-Malt-Whisky

            Czorneboh