MySQL to older MariaDB - slower performance












0














so I have a problem with DB migration from one webserver to another.
Server 1 has MySQL version 5.6 running under cPanel hosting...
Server 2 has MariaDB version 5.5 running under Webmin/Virtualmin
PHP version is the same on both of them...5.6



Anyway, I wanted to move a site from Server 1 to 2. I exported the DB using HeidiSQL and then imported the data on Server 2. The data imported fine, but the performance of the queries is worse by a factor of 10x. I went over the buffer size variables and all other "key" variables and they are the same or increased on Server 2.
I tried changing the storage engine from MyIsam to Aria or InnoDB but the results were the same...I also optimized the whole DB but again no luck. Indexes are the same on both servers.



I then decided to host the DB back on the original server and just load the files from the new one....I exported the new DB (only data using insert ignore) and imported that SQL back to Server 1. Immediately after the import the original DB started performing slowly as well...
Unless I use the original backup from when I moved the DB the first time, no matter how I update the DB to new data it starts performing poorly...



Example of query that takes 35 secs to run now when it used to take 3 secs:



select  p.*, pd.ID detailID,
s.title subject, s.displayTitle, s.memberPanCode,
s.virtualDelivery,
CASE WHEN (DATE_ADD(p.releaseDate, INTERVAL 2 WEEK) > NOW()) THEN 1 ELSE 0 END pNew,
CASE WHEN(s.publicChoice=1) THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN(s.displayTitle=1) THEN s.ID ELSE '0' END subjectID from sProduct p
inner join sProductDetail pd ON pd.ID_sProduct=p.ID
left join sProductDetailWarehouse pdw ON pdw.ID_sProductDetail=pd.ID
left join sProductDetailSubjectPrice pdsp ON pdsp.ID_sProductDetail=pd.ID
left join sSubject s ON (s.memberPanCode=pdsp.memberPanCode
and s.shownOnSite=1)
where ( s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
AND ( (pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL )
OR (pd.ID > 0 and p.ID_sSupplier > 0 )
OR (pd.ID > 0 and pdsp.ID IS NULL )
OR (pd.ID > 0 and s.displayTitle IS NULL )
)
AND (DATE_ADD(NOW(), INTERVAL 1 DAY) > p.showDate)
AND ( pdw.stock > 0
OR pd.stock > 0
OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3')
)
and p.published IN (1,2)
GROUP BY p.ID, s.memberPanCode
order by p.showDate desc
limit 3


DB structure can be found here: https://igabiba.si/images/biba_scheme.sql



Explain statement for the new, slower DB:
enter image description here



Explain statement for the older, faster DB:
enter image description here



Any idea what is there left to check? What can I do to solve this?



Thank you for helping










share|improve this question
























  • what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
    – NashPL
    Nov 6 at 9:38










  • It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
    – Bostjan
    Nov 6 at 9:41










  • There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
    – Rick James
    Nov 6 at 17:01






  • 1




    Added the explain statements as well...
    – Bostjan
    Nov 8 at 13:10






  • 1




    It looks like there is a different set of indexes on the two machines??
    – Rick James
    Nov 8 at 21:30
















0














so I have a problem with DB migration from one webserver to another.
Server 1 has MySQL version 5.6 running under cPanel hosting...
Server 2 has MariaDB version 5.5 running under Webmin/Virtualmin
PHP version is the same on both of them...5.6



Anyway, I wanted to move a site from Server 1 to 2. I exported the DB using HeidiSQL and then imported the data on Server 2. The data imported fine, but the performance of the queries is worse by a factor of 10x. I went over the buffer size variables and all other "key" variables and they are the same or increased on Server 2.
I tried changing the storage engine from MyIsam to Aria or InnoDB but the results were the same...I also optimized the whole DB but again no luck. Indexes are the same on both servers.



I then decided to host the DB back on the original server and just load the files from the new one....I exported the new DB (only data using insert ignore) and imported that SQL back to Server 1. Immediately after the import the original DB started performing slowly as well...
Unless I use the original backup from when I moved the DB the first time, no matter how I update the DB to new data it starts performing poorly...



Example of query that takes 35 secs to run now when it used to take 3 secs:



select  p.*, pd.ID detailID,
s.title subject, s.displayTitle, s.memberPanCode,
s.virtualDelivery,
CASE WHEN (DATE_ADD(p.releaseDate, INTERVAL 2 WEEK) > NOW()) THEN 1 ELSE 0 END pNew,
CASE WHEN(s.publicChoice=1) THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN(s.displayTitle=1) THEN s.ID ELSE '0' END subjectID from sProduct p
inner join sProductDetail pd ON pd.ID_sProduct=p.ID
left join sProductDetailWarehouse pdw ON pdw.ID_sProductDetail=pd.ID
left join sProductDetailSubjectPrice pdsp ON pdsp.ID_sProductDetail=pd.ID
left join sSubject s ON (s.memberPanCode=pdsp.memberPanCode
and s.shownOnSite=1)
where ( s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
AND ( (pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL )
OR (pd.ID > 0 and p.ID_sSupplier > 0 )
OR (pd.ID > 0 and pdsp.ID IS NULL )
OR (pd.ID > 0 and s.displayTitle IS NULL )
)
AND (DATE_ADD(NOW(), INTERVAL 1 DAY) > p.showDate)
AND ( pdw.stock > 0
OR pd.stock > 0
OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3')
)
and p.published IN (1,2)
GROUP BY p.ID, s.memberPanCode
order by p.showDate desc
limit 3


DB structure can be found here: https://igabiba.si/images/biba_scheme.sql



Explain statement for the new, slower DB:
enter image description here



Explain statement for the older, faster DB:
enter image description here



Any idea what is there left to check? What can I do to solve this?



Thank you for helping










share|improve this question
























  • what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
    – NashPL
    Nov 6 at 9:38










  • It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
    – Bostjan
    Nov 6 at 9:41










  • There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
    – Rick James
    Nov 6 at 17:01






  • 1




    Added the explain statements as well...
    – Bostjan
    Nov 8 at 13:10






  • 1




    It looks like there is a different set of indexes on the two machines??
    – Rick James
    Nov 8 at 21:30














0












0








0







so I have a problem with DB migration from one webserver to another.
Server 1 has MySQL version 5.6 running under cPanel hosting...
Server 2 has MariaDB version 5.5 running under Webmin/Virtualmin
PHP version is the same on both of them...5.6



Anyway, I wanted to move a site from Server 1 to 2. I exported the DB using HeidiSQL and then imported the data on Server 2. The data imported fine, but the performance of the queries is worse by a factor of 10x. I went over the buffer size variables and all other "key" variables and they are the same or increased on Server 2.
I tried changing the storage engine from MyIsam to Aria or InnoDB but the results were the same...I also optimized the whole DB but again no luck. Indexes are the same on both servers.



I then decided to host the DB back on the original server and just load the files from the new one....I exported the new DB (only data using insert ignore) and imported that SQL back to Server 1. Immediately after the import the original DB started performing slowly as well...
Unless I use the original backup from when I moved the DB the first time, no matter how I update the DB to new data it starts performing poorly...



Example of query that takes 35 secs to run now when it used to take 3 secs:



select  p.*, pd.ID detailID,
s.title subject, s.displayTitle, s.memberPanCode,
s.virtualDelivery,
CASE WHEN (DATE_ADD(p.releaseDate, INTERVAL 2 WEEK) > NOW()) THEN 1 ELSE 0 END pNew,
CASE WHEN(s.publicChoice=1) THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN(s.displayTitle=1) THEN s.ID ELSE '0' END subjectID from sProduct p
inner join sProductDetail pd ON pd.ID_sProduct=p.ID
left join sProductDetailWarehouse pdw ON pdw.ID_sProductDetail=pd.ID
left join sProductDetailSubjectPrice pdsp ON pdsp.ID_sProductDetail=pd.ID
left join sSubject s ON (s.memberPanCode=pdsp.memberPanCode
and s.shownOnSite=1)
where ( s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
AND ( (pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL )
OR (pd.ID > 0 and p.ID_sSupplier > 0 )
OR (pd.ID > 0 and pdsp.ID IS NULL )
OR (pd.ID > 0 and s.displayTitle IS NULL )
)
AND (DATE_ADD(NOW(), INTERVAL 1 DAY) > p.showDate)
AND ( pdw.stock > 0
OR pd.stock > 0
OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3')
)
and p.published IN (1,2)
GROUP BY p.ID, s.memberPanCode
order by p.showDate desc
limit 3


DB structure can be found here: https://igabiba.si/images/biba_scheme.sql



Explain statement for the new, slower DB:
enter image description here



Explain statement for the older, faster DB:
enter image description here



Any idea what is there left to check? What can I do to solve this?



Thank you for helping










share|improve this question















so I have a problem with DB migration from one webserver to another.
Server 1 has MySQL version 5.6 running under cPanel hosting...
Server 2 has MariaDB version 5.5 running under Webmin/Virtualmin
PHP version is the same on both of them...5.6



Anyway, I wanted to move a site from Server 1 to 2. I exported the DB using HeidiSQL and then imported the data on Server 2. The data imported fine, but the performance of the queries is worse by a factor of 10x. I went over the buffer size variables and all other "key" variables and they are the same or increased on Server 2.
I tried changing the storage engine from MyIsam to Aria or InnoDB but the results were the same...I also optimized the whole DB but again no luck. Indexes are the same on both servers.



I then decided to host the DB back on the original server and just load the files from the new one....I exported the new DB (only data using insert ignore) and imported that SQL back to Server 1. Immediately after the import the original DB started performing slowly as well...
Unless I use the original backup from when I moved the DB the first time, no matter how I update the DB to new data it starts performing poorly...



Example of query that takes 35 secs to run now when it used to take 3 secs:



select  p.*, pd.ID detailID,
s.title subject, s.displayTitle, s.memberPanCode,
s.virtualDelivery,
CASE WHEN (DATE_ADD(p.releaseDate, INTERVAL 2 WEEK) > NOW()) THEN 1 ELSE 0 END pNew,
CASE WHEN(s.publicChoice=1) THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN(s.displayTitle=1) THEN s.ID ELSE '0' END subjectID from sProduct p
inner join sProductDetail pd ON pd.ID_sProduct=p.ID
left join sProductDetailWarehouse pdw ON pdw.ID_sProductDetail=pd.ID
left join sProductDetailSubjectPrice pdsp ON pdsp.ID_sProductDetail=pd.ID
left join sSubject s ON (s.memberPanCode=pdsp.memberPanCode
and s.shownOnSite=1)
where ( s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
AND ( (pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL )
OR (pd.ID > 0 and p.ID_sSupplier > 0 )
OR (pd.ID > 0 and pdsp.ID IS NULL )
OR (pd.ID > 0 and s.displayTitle IS NULL )
)
AND (DATE_ADD(NOW(), INTERVAL 1 DAY) > p.showDate)
AND ( pdw.stock > 0
OR pd.stock > 0
OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3')
)
and p.published IN (1,2)
GROUP BY p.ID, s.memberPanCode
order by p.showDate desc
limit 3


DB structure can be found here: https://igabiba.si/images/biba_scheme.sql



Explain statement for the new, slower DB:
enter image description here



Explain statement for the older, faster DB:
enter image description here



Any idea what is there left to check? What can I do to solve this?



Thank you for helping







php mysql performance mariadb






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 17:03









Rick James

65.8k55797




65.8k55797










asked Nov 6 at 9:32









Bostjan

66831631




66831631












  • what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
    – NashPL
    Nov 6 at 9:38










  • It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
    – Bostjan
    Nov 6 at 9:41










  • There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
    – Rick James
    Nov 6 at 17:01






  • 1




    Added the explain statements as well...
    – Bostjan
    Nov 8 at 13:10






  • 1




    It looks like there is a different set of indexes on the two machines??
    – Rick James
    Nov 8 at 21:30


















  • what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
    – NashPL
    Nov 6 at 9:38










  • It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
    – Bostjan
    Nov 6 at 9:41










  • There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
    – Rick James
    Nov 6 at 17:01






  • 1




    Added the explain statements as well...
    – Bostjan
    Nov 8 at 13:10






  • 1




    It looks like there is a different set of indexes on the two machines??
    – Rick James
    Nov 8 at 21:30
















what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
– NashPL
Nov 6 at 9:38




what are the spec of the machines, what are the network interfaces(network problem?) I assume you are running under newest MariaDB ?
– NashPL
Nov 6 at 9:38












It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
– Bostjan
Nov 6 at 9:41




It's the same machine really, hardware spec is the same for both of them (to the tiniest detail). I'm running the newest MariaDB officially supported by Virtualmin, which is 5.5 sadly
– Bostjan
Nov 6 at 9:41












There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
– Rick James
Nov 6 at 17:01




There are a zillion possibilities. To speed up the search... If you have identified any query that seems to be slower, let's study it. If not, turn on the slowlog with long_query_time=0.2, gather the results for a day, summarize via pt-query-digest, then let's look at the top couple of slow queries. From that, we should be able to work backward to what the real cause is.
– Rick James
Nov 6 at 17:01




1




1




Added the explain statements as well...
– Bostjan
Nov 8 at 13:10




Added the explain statements as well...
– Bostjan
Nov 8 at 13:10




1




1




It looks like there is a different set of indexes on the two machines??
– Rick James
Nov 8 at 21:30




It looks like there is a different set of indexes on the two machines??
– Rick James
Nov 8 at 21:30












3 Answers
3






active

oldest

votes


















1





+100









How big are the tables? InnoDB now does FULLTEXT. MyISAM is being orphaned. I agree with not using something as old as 5.5. MariaDB has 10.0, 10.1, 10.2, 10.3. MySQL has 5.6, 5.7, 8.0. And there has been a lot of optimization work done in most of those. By backtracking to 5.5, you probably lost some optimization features. Alas, I have not spotted the specific thing that is lost.



The ORs are deadly for performance. They essentially prevent the use of indexes. I don't see any obvious way to rearrange things -- since the ORs are across multiple tables.



Here are some composite, covering, indexes that might help:



pd:   INDEX(ID_sProduct, ID, stock)  -- perhaps this order is best
pdw: INDEX(ID_sProductDetail, stock) -- in this order
pdsp: INDEX(ID_sProductDetail, memberPanCode, ID) -- in this order
s: INDEX(memberPanCode, shownOnSite) -- in either order


Also, add



p:  INDEX(showDate, published, ID, ID_sSupplier) -- in this order


and restructure the query by pulling p.* out of the main flow. Currently the bulky p.* is hauled through the joins, etc before whittling down to only 3 rows. By restructuring, we can find which 3 rows first, then fetch all the stuff:



SELECT p2.*, etc.
p2.releaseDate > NOW() - INTERVAL 2 WEEK AS pNew,
etc.
FROM (
SELECT toss p.*, add p.ID, keep other columns
FROM ...
LEFT JOIN ...
ORDER BY...
LIMIT 3
) AS x
JOIN sProduct AS p2 ON x.ID = p2.ID
ORDER BY p2.showDate desc


That new index is "covering" in that all the uses of p in the subquery are in the index. I observed that releaseDate could be left out and picked up with the second use of sProduct.



I put sShowDate first in the index on the assumption that it does at least some filtering (p.showDate < NOW + INTERVAL 1 DAY).



The GROUP BY and ORDER BY combination necessitates one or two filesorts; they cannot be eliminated. What I have done is minimize their cost by making them less bulky.






share|improve this answer























  • Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
    – Bostjan
    Nov 8 at 20:09












  • @Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
    – Rick James
    Nov 8 at 20:12










  • Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
    – Bostjan
    Nov 8 at 20:14






  • 1




    @Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
    – Rick James
    Nov 8 at 21:32










  • I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
    – Bostjan
    Nov 13 at 14:12



















0














This query is pretty rank, those WHERE conditions are needlessly complicated



Your original query (formatted)



   SELECT p.*,
pd.ID,
detailID, /** include table alias? */
s.title subject,
s.displayTitle,
s.memberPanCode,
s.virtualDelivery,
(p.releaseDate < NOW() - INTERVAL 2 WEEK) pNew /** Booleans are resolve to 1/0 in MySQL */
CASE WHEN s.publicChoice = 1 THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN s.displayTitle = 1 THEN s.ID ELSE '0' END subjectID

FROM sProduct p

JOIN sProductDetail pd
ON pd.ID_sProduct = p.ID

LEFT JOIN sProductDetailWarehouse pdw
ON pdw.ID_sProductDetail = pd.ID

LEFT JOIN sProductDetailSubjectPrice pdsp
ON pdsp.ID_sProductDetail = pd.ID

LEFT JOIN sSubject s
ON s.memberPanCode = pdsp.memberPanCode
AND s.shownOnSite=1

WHERE (s.publicChoice=1 OR s.defaultSubject=1 OR s.memberPanCode='' OR s.memberPanCode IS NULL)
AND /** (
(pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL)
OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)
OR (pd.ID > 0 AND s.displayTitle IS NULL)
) */ pd.ID > 0 /** see below */
AND p.showDate < NOW() + INTERVAL 1 DAY
AND (pdw.stock > 0 OR pd.stock > 0 OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3'))
AND p.published IN (1,2)

GROUP BY p.ID, s.memberPanCode
ORDER BY p.showDate DESC
LIMIT 3


Let's start with this condition



  AND (
/** This with the last subcondition is just pd.ID > 0 */
(pd.ID > 0 AND s.displayTitle IS NOT NULL)

/** This is impossible due to your INNER JOIN */
OR (pd.ID IS NULL AND s.displayTitle IS NULL)

OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)

/** This with the first subcondition is just pd.ID > 0 */
OR (pd.ID > 0 AND s.displayTitle IS NULL)
)


That whole condition resolves to pd.ID > 0, which is always TRUE unless you have manually added a product with ID of 0



I suspect (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3') can become just p.ID_sSupplier <> 3 for the same reason



This first condition seems super inclusive too



WHERE (
s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
...


Which leads me to question which rows you are actually trying to avoid with this condition?



That GROUP BY clause is worrisome too, as you have no aggregate columns selected.. a lot of your final columns will be arbitrarily selected



What are you actually trying to achieve with this query?



It's worth remembering that OR conditions tend to be slower to resolve than AND conditions when using queries






share|improve this answer

















  • 1




    Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
    – Bostjan
    Nov 8 at 20:11












  • No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
    – Arth
    Nov 12 at 17:17



















0














The execution plans (show in the EXPLAIN output) are different. So we reasonably expect different performance characteristics.



As @RickJames pointed out in a comment, there seem to be some indexes missing in the target environment.



The question states: "Indexes are the same on both servers."



But the information provided leads us to a conclusion that the indexs are not the same.



We see some indexes referenced in the output of the first EXPLAIN. And those index names are not found in the output of the second EXPLAIN. Those index names are also not found in the schema definition script.





Q: Why are some of the indexes (reported in the first EXPLAIN missing) from the schema definition?



Q: Was the output from mysqldump file for the migration modified to remove some index definitions?



Q: Was some tool other than mysqldump used to extract the schema definition for the migration, and were the indexes were omitted?



Q: Did some "create index" statements fail to execute in the target environment? (Possibly because of limits on sizes of columns in indexes?)





Or maybe I have it the other way around, maybe there are indexes that were added in the target that didn't exist in the source.






share|improve this answer























  • Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
    – Bostjan
    Nov 13 at 7:56











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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%2fstackoverflow.com%2fquestions%2f53169118%2fmysql-to-older-mariadb-slower-performance%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









1





+100









How big are the tables? InnoDB now does FULLTEXT. MyISAM is being orphaned. I agree with not using something as old as 5.5. MariaDB has 10.0, 10.1, 10.2, 10.3. MySQL has 5.6, 5.7, 8.0. And there has been a lot of optimization work done in most of those. By backtracking to 5.5, you probably lost some optimization features. Alas, I have not spotted the specific thing that is lost.



The ORs are deadly for performance. They essentially prevent the use of indexes. I don't see any obvious way to rearrange things -- since the ORs are across multiple tables.



Here are some composite, covering, indexes that might help:



pd:   INDEX(ID_sProduct, ID, stock)  -- perhaps this order is best
pdw: INDEX(ID_sProductDetail, stock) -- in this order
pdsp: INDEX(ID_sProductDetail, memberPanCode, ID) -- in this order
s: INDEX(memberPanCode, shownOnSite) -- in either order


Also, add



p:  INDEX(showDate, published, ID, ID_sSupplier) -- in this order


and restructure the query by pulling p.* out of the main flow. Currently the bulky p.* is hauled through the joins, etc before whittling down to only 3 rows. By restructuring, we can find which 3 rows first, then fetch all the stuff:



SELECT p2.*, etc.
p2.releaseDate > NOW() - INTERVAL 2 WEEK AS pNew,
etc.
FROM (
SELECT toss p.*, add p.ID, keep other columns
FROM ...
LEFT JOIN ...
ORDER BY...
LIMIT 3
) AS x
JOIN sProduct AS p2 ON x.ID = p2.ID
ORDER BY p2.showDate desc


That new index is "covering" in that all the uses of p in the subquery are in the index. I observed that releaseDate could be left out and picked up with the second use of sProduct.



I put sShowDate first in the index on the assumption that it does at least some filtering (p.showDate < NOW + INTERVAL 1 DAY).



The GROUP BY and ORDER BY combination necessitates one or two filesorts; they cannot be eliminated. What I have done is minimize their cost by making them less bulky.






share|improve this answer























  • Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
    – Bostjan
    Nov 8 at 20:09












  • @Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
    – Rick James
    Nov 8 at 20:12










  • Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
    – Bostjan
    Nov 8 at 20:14






  • 1




    @Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
    – Rick James
    Nov 8 at 21:32










  • I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
    – Bostjan
    Nov 13 at 14:12
















1





+100









How big are the tables? InnoDB now does FULLTEXT. MyISAM is being orphaned. I agree with not using something as old as 5.5. MariaDB has 10.0, 10.1, 10.2, 10.3. MySQL has 5.6, 5.7, 8.0. And there has been a lot of optimization work done in most of those. By backtracking to 5.5, you probably lost some optimization features. Alas, I have not spotted the specific thing that is lost.



The ORs are deadly for performance. They essentially prevent the use of indexes. I don't see any obvious way to rearrange things -- since the ORs are across multiple tables.



Here are some composite, covering, indexes that might help:



pd:   INDEX(ID_sProduct, ID, stock)  -- perhaps this order is best
pdw: INDEX(ID_sProductDetail, stock) -- in this order
pdsp: INDEX(ID_sProductDetail, memberPanCode, ID) -- in this order
s: INDEX(memberPanCode, shownOnSite) -- in either order


Also, add



p:  INDEX(showDate, published, ID, ID_sSupplier) -- in this order


and restructure the query by pulling p.* out of the main flow. Currently the bulky p.* is hauled through the joins, etc before whittling down to only 3 rows. By restructuring, we can find which 3 rows first, then fetch all the stuff:



SELECT p2.*, etc.
p2.releaseDate > NOW() - INTERVAL 2 WEEK AS pNew,
etc.
FROM (
SELECT toss p.*, add p.ID, keep other columns
FROM ...
LEFT JOIN ...
ORDER BY...
LIMIT 3
) AS x
JOIN sProduct AS p2 ON x.ID = p2.ID
ORDER BY p2.showDate desc


That new index is "covering" in that all the uses of p in the subquery are in the index. I observed that releaseDate could be left out and picked up with the second use of sProduct.



I put sShowDate first in the index on the assumption that it does at least some filtering (p.showDate < NOW + INTERVAL 1 DAY).



The GROUP BY and ORDER BY combination necessitates one or two filesorts; they cannot be eliminated. What I have done is minimize their cost by making them less bulky.






share|improve this answer























  • Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
    – Bostjan
    Nov 8 at 20:09












  • @Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
    – Rick James
    Nov 8 at 20:12










  • Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
    – Bostjan
    Nov 8 at 20:14






  • 1




    @Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
    – Rick James
    Nov 8 at 21:32










  • I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
    – Bostjan
    Nov 13 at 14:12














1





+100







1





+100



1




+100




How big are the tables? InnoDB now does FULLTEXT. MyISAM is being orphaned. I agree with not using something as old as 5.5. MariaDB has 10.0, 10.1, 10.2, 10.3. MySQL has 5.6, 5.7, 8.0. And there has been a lot of optimization work done in most of those. By backtracking to 5.5, you probably lost some optimization features. Alas, I have not spotted the specific thing that is lost.



The ORs are deadly for performance. They essentially prevent the use of indexes. I don't see any obvious way to rearrange things -- since the ORs are across multiple tables.



Here are some composite, covering, indexes that might help:



pd:   INDEX(ID_sProduct, ID, stock)  -- perhaps this order is best
pdw: INDEX(ID_sProductDetail, stock) -- in this order
pdsp: INDEX(ID_sProductDetail, memberPanCode, ID) -- in this order
s: INDEX(memberPanCode, shownOnSite) -- in either order


Also, add



p:  INDEX(showDate, published, ID, ID_sSupplier) -- in this order


and restructure the query by pulling p.* out of the main flow. Currently the bulky p.* is hauled through the joins, etc before whittling down to only 3 rows. By restructuring, we can find which 3 rows first, then fetch all the stuff:



SELECT p2.*, etc.
p2.releaseDate > NOW() - INTERVAL 2 WEEK AS pNew,
etc.
FROM (
SELECT toss p.*, add p.ID, keep other columns
FROM ...
LEFT JOIN ...
ORDER BY...
LIMIT 3
) AS x
JOIN sProduct AS p2 ON x.ID = p2.ID
ORDER BY p2.showDate desc


That new index is "covering" in that all the uses of p in the subquery are in the index. I observed that releaseDate could be left out and picked up with the second use of sProduct.



I put sShowDate first in the index on the assumption that it does at least some filtering (p.showDate < NOW + INTERVAL 1 DAY).



The GROUP BY and ORDER BY combination necessitates one or two filesorts; they cannot be eliminated. What I have done is minimize their cost by making them less bulky.






share|improve this answer














How big are the tables? InnoDB now does FULLTEXT. MyISAM is being orphaned. I agree with not using something as old as 5.5. MariaDB has 10.0, 10.1, 10.2, 10.3. MySQL has 5.6, 5.7, 8.0. And there has been a lot of optimization work done in most of those. By backtracking to 5.5, you probably lost some optimization features. Alas, I have not spotted the specific thing that is lost.



The ORs are deadly for performance. They essentially prevent the use of indexes. I don't see any obvious way to rearrange things -- since the ORs are across multiple tables.



Here are some composite, covering, indexes that might help:



pd:   INDEX(ID_sProduct, ID, stock)  -- perhaps this order is best
pdw: INDEX(ID_sProductDetail, stock) -- in this order
pdsp: INDEX(ID_sProductDetail, memberPanCode, ID) -- in this order
s: INDEX(memberPanCode, shownOnSite) -- in either order


Also, add



p:  INDEX(showDate, published, ID, ID_sSupplier) -- in this order


and restructure the query by pulling p.* out of the main flow. Currently the bulky p.* is hauled through the joins, etc before whittling down to only 3 rows. By restructuring, we can find which 3 rows first, then fetch all the stuff:



SELECT p2.*, etc.
p2.releaseDate > NOW() - INTERVAL 2 WEEK AS pNew,
etc.
FROM (
SELECT toss p.*, add p.ID, keep other columns
FROM ...
LEFT JOIN ...
ORDER BY...
LIMIT 3
) AS x
JOIN sProduct AS p2 ON x.ID = p2.ID
ORDER BY p2.showDate desc


That new index is "covering" in that all the uses of p in the subquery are in the index. I observed that releaseDate could be left out and picked up with the second use of sProduct.



I put sShowDate first in the index on the assumption that it does at least some filtering (p.showDate < NOW + INTERVAL 1 DAY).



The GROUP BY and ORDER BY combination necessitates one or two filesorts; they cannot be eliminated. What I have done is minimize their cost by making them less bulky.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 8 at 21:32

























answered Nov 8 at 16:37









Rick James

65.8k55797




65.8k55797












  • Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
    – Bostjan
    Nov 8 at 20:09












  • @Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
    – Rick James
    Nov 8 at 20:12










  • Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
    – Bostjan
    Nov 8 at 20:14






  • 1




    @Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
    – Rick James
    Nov 8 at 21:32










  • I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
    – Bostjan
    Nov 13 at 14:12


















  • Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
    – Bostjan
    Nov 8 at 20:09












  • @Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
    – Rick James
    Nov 8 at 20:12










  • Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
    – Bostjan
    Nov 8 at 20:14






  • 1




    @Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
    – Rick James
    Nov 8 at 21:32










  • I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
    – Bostjan
    Nov 13 at 14:12
















Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
– Bostjan
Nov 8 at 20:09






Hi, thank you very much for taking the time to answer. I will most definitely be going over the queries and trying to optimize them. Your answer will most certainly point me to the right direction. I have to say though that the reason for starting this question was the difference between the two DB when it came to performance on the same set of data...I just can't figure out why one is so faster than the other.
– Bostjan
Nov 8 at 20:09














@Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
– Rick James
Nov 8 at 20:12




@Bostjan - My Answer was a consolation prize for you -- I could not figure out the specific reason for the difference. (The un-specific reason is that 5.5 is older, hence possibly slower.)
– Rick James
Nov 8 at 20:12












Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
– Bostjan
Nov 8 at 20:14




Thank you :) it most certainly is a very big nudge in the right direction. There is just a feeling I have that I must be missing something trivial for such a difference to occur.
– Bostjan
Nov 8 at 20:14




1




1




@Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
– Rick James
Nov 8 at 21:32




@Bostjan - glancing again at the EXPLAINs, I noticed that there might be an index on one machine that was not on the other. I added a recommendation for s.
– Rick James
Nov 8 at 21:32












I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
– Bostjan
Nov 13 at 14:12




I'm awarding the bounty to this answer even though the problem still exists. It just seems to me there is something wrong/corrupt in the new DB
– Bostjan
Nov 13 at 14:12













0














This query is pretty rank, those WHERE conditions are needlessly complicated



Your original query (formatted)



   SELECT p.*,
pd.ID,
detailID, /** include table alias? */
s.title subject,
s.displayTitle,
s.memberPanCode,
s.virtualDelivery,
(p.releaseDate < NOW() - INTERVAL 2 WEEK) pNew /** Booleans are resolve to 1/0 in MySQL */
CASE WHEN s.publicChoice = 1 THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN s.displayTitle = 1 THEN s.ID ELSE '0' END subjectID

FROM sProduct p

JOIN sProductDetail pd
ON pd.ID_sProduct = p.ID

LEFT JOIN sProductDetailWarehouse pdw
ON pdw.ID_sProductDetail = pd.ID

LEFT JOIN sProductDetailSubjectPrice pdsp
ON pdsp.ID_sProductDetail = pd.ID

LEFT JOIN sSubject s
ON s.memberPanCode = pdsp.memberPanCode
AND s.shownOnSite=1

WHERE (s.publicChoice=1 OR s.defaultSubject=1 OR s.memberPanCode='' OR s.memberPanCode IS NULL)
AND /** (
(pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL)
OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)
OR (pd.ID > 0 AND s.displayTitle IS NULL)
) */ pd.ID > 0 /** see below */
AND p.showDate < NOW() + INTERVAL 1 DAY
AND (pdw.stock > 0 OR pd.stock > 0 OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3'))
AND p.published IN (1,2)

GROUP BY p.ID, s.memberPanCode
ORDER BY p.showDate DESC
LIMIT 3


Let's start with this condition



  AND (
/** This with the last subcondition is just pd.ID > 0 */
(pd.ID > 0 AND s.displayTitle IS NOT NULL)

/** This is impossible due to your INNER JOIN */
OR (pd.ID IS NULL AND s.displayTitle IS NULL)

OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)

/** This with the first subcondition is just pd.ID > 0 */
OR (pd.ID > 0 AND s.displayTitle IS NULL)
)


That whole condition resolves to pd.ID > 0, which is always TRUE unless you have manually added a product with ID of 0



I suspect (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3') can become just p.ID_sSupplier <> 3 for the same reason



This first condition seems super inclusive too



WHERE (
s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
...


Which leads me to question which rows you are actually trying to avoid with this condition?



That GROUP BY clause is worrisome too, as you have no aggregate columns selected.. a lot of your final columns will be arbitrarily selected



What are you actually trying to achieve with this query?



It's worth remembering that OR conditions tend to be slower to resolve than AND conditions when using queries






share|improve this answer

















  • 1




    Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
    – Bostjan
    Nov 8 at 20:11












  • No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
    – Arth
    Nov 12 at 17:17
















0














This query is pretty rank, those WHERE conditions are needlessly complicated



Your original query (formatted)



   SELECT p.*,
pd.ID,
detailID, /** include table alias? */
s.title subject,
s.displayTitle,
s.memberPanCode,
s.virtualDelivery,
(p.releaseDate < NOW() - INTERVAL 2 WEEK) pNew /** Booleans are resolve to 1/0 in MySQL */
CASE WHEN s.publicChoice = 1 THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN s.displayTitle = 1 THEN s.ID ELSE '0' END subjectID

FROM sProduct p

JOIN sProductDetail pd
ON pd.ID_sProduct = p.ID

LEFT JOIN sProductDetailWarehouse pdw
ON pdw.ID_sProductDetail = pd.ID

LEFT JOIN sProductDetailSubjectPrice pdsp
ON pdsp.ID_sProductDetail = pd.ID

LEFT JOIN sSubject s
ON s.memberPanCode = pdsp.memberPanCode
AND s.shownOnSite=1

WHERE (s.publicChoice=1 OR s.defaultSubject=1 OR s.memberPanCode='' OR s.memberPanCode IS NULL)
AND /** (
(pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL)
OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)
OR (pd.ID > 0 AND s.displayTitle IS NULL)
) */ pd.ID > 0 /** see below */
AND p.showDate < NOW() + INTERVAL 1 DAY
AND (pdw.stock > 0 OR pd.stock > 0 OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3'))
AND p.published IN (1,2)

GROUP BY p.ID, s.memberPanCode
ORDER BY p.showDate DESC
LIMIT 3


Let's start with this condition



  AND (
/** This with the last subcondition is just pd.ID > 0 */
(pd.ID > 0 AND s.displayTitle IS NOT NULL)

/** This is impossible due to your INNER JOIN */
OR (pd.ID IS NULL AND s.displayTitle IS NULL)

OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)

/** This with the first subcondition is just pd.ID > 0 */
OR (pd.ID > 0 AND s.displayTitle IS NULL)
)


That whole condition resolves to pd.ID > 0, which is always TRUE unless you have manually added a product with ID of 0



I suspect (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3') can become just p.ID_sSupplier <> 3 for the same reason



This first condition seems super inclusive too



WHERE (
s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
...


Which leads me to question which rows you are actually trying to avoid with this condition?



That GROUP BY clause is worrisome too, as you have no aggregate columns selected.. a lot of your final columns will be arbitrarily selected



What are you actually trying to achieve with this query?



It's worth remembering that OR conditions tend to be slower to resolve than AND conditions when using queries






share|improve this answer

















  • 1




    Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
    – Bostjan
    Nov 8 at 20:11












  • No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
    – Arth
    Nov 12 at 17:17














0












0








0






This query is pretty rank, those WHERE conditions are needlessly complicated



Your original query (formatted)



   SELECT p.*,
pd.ID,
detailID, /** include table alias? */
s.title subject,
s.displayTitle,
s.memberPanCode,
s.virtualDelivery,
(p.releaseDate < NOW() - INTERVAL 2 WEEK) pNew /** Booleans are resolve to 1/0 in MySQL */
CASE WHEN s.publicChoice = 1 THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN s.displayTitle = 1 THEN s.ID ELSE '0' END subjectID

FROM sProduct p

JOIN sProductDetail pd
ON pd.ID_sProduct = p.ID

LEFT JOIN sProductDetailWarehouse pdw
ON pdw.ID_sProductDetail = pd.ID

LEFT JOIN sProductDetailSubjectPrice pdsp
ON pdsp.ID_sProductDetail = pd.ID

LEFT JOIN sSubject s
ON s.memberPanCode = pdsp.memberPanCode
AND s.shownOnSite=1

WHERE (s.publicChoice=1 OR s.defaultSubject=1 OR s.memberPanCode='' OR s.memberPanCode IS NULL)
AND /** (
(pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL)
OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)
OR (pd.ID > 0 AND s.displayTitle IS NULL)
) */ pd.ID > 0 /** see below */
AND p.showDate < NOW() + INTERVAL 1 DAY
AND (pdw.stock > 0 OR pd.stock > 0 OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3'))
AND p.published IN (1,2)

GROUP BY p.ID, s.memberPanCode
ORDER BY p.showDate DESC
LIMIT 3


Let's start with this condition



  AND (
/** This with the last subcondition is just pd.ID > 0 */
(pd.ID > 0 AND s.displayTitle IS NOT NULL)

/** This is impossible due to your INNER JOIN */
OR (pd.ID IS NULL AND s.displayTitle IS NULL)

OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)

/** This with the first subcondition is just pd.ID > 0 */
OR (pd.ID > 0 AND s.displayTitle IS NULL)
)


That whole condition resolves to pd.ID > 0, which is always TRUE unless you have manually added a product with ID of 0



I suspect (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3') can become just p.ID_sSupplier <> 3 for the same reason



This first condition seems super inclusive too



WHERE (
s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
...


Which leads me to question which rows you are actually trying to avoid with this condition?



That GROUP BY clause is worrisome too, as you have no aggregate columns selected.. a lot of your final columns will be arbitrarily selected



What are you actually trying to achieve with this query?



It's worth remembering that OR conditions tend to be slower to resolve than AND conditions when using queries






share|improve this answer












This query is pretty rank, those WHERE conditions are needlessly complicated



Your original query (formatted)



   SELECT p.*,
pd.ID,
detailID, /** include table alias? */
s.title subject,
s.displayTitle,
s.memberPanCode,
s.virtualDelivery,
(p.releaseDate < NOW() - INTERVAL 2 WEEK) pNew /** Booleans are resolve to 1/0 in MySQL */
CASE WHEN s.publicChoice = 1 THEN s.memberPanCode ELSE '' END usableSubject,
CASE WHEN s.displayTitle = 1 THEN s.ID ELSE '0' END subjectID

FROM sProduct p

JOIN sProductDetail pd
ON pd.ID_sProduct = p.ID

LEFT JOIN sProductDetailWarehouse pdw
ON pdw.ID_sProductDetail = pd.ID

LEFT JOIN sProductDetailSubjectPrice pdsp
ON pdsp.ID_sProductDetail = pd.ID

LEFT JOIN sSubject s
ON s.memberPanCode = pdsp.memberPanCode
AND s.shownOnSite=1

WHERE (s.publicChoice=1 OR s.defaultSubject=1 OR s.memberPanCode='' OR s.memberPanCode IS NULL)
AND /** (
(pd.ID > 0 AND s.displayTitle IS NOT NULL)
OR (pd.ID IS NULL AND s.displayTitle IS NULL)
OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)
OR (pd.ID > 0 AND s.displayTitle IS NULL)
) */ pd.ID > 0 /** see below */
AND p.showDate < NOW() + INTERVAL 1 DAY
AND (pdw.stock > 0 OR pd.stock > 0 OR (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3'))
AND p.published IN (1,2)

GROUP BY p.ID, s.memberPanCode
ORDER BY p.showDate DESC
LIMIT 3


Let's start with this condition



  AND (
/** This with the last subcondition is just pd.ID > 0 */
(pd.ID > 0 AND s.displayTitle IS NOT NULL)

/** This is impossible due to your INNER JOIN */
OR (pd.ID IS NULL AND s.displayTitle IS NULL)

OR (pd.ID > 0 AND p.ID_sSupplier > 0)
OR (pd.ID > 0 AND pdsp.ID IS NULL)

/** This with the first subcondition is just pd.ID > 0 */
OR (pd.ID > 0 AND s.displayTitle IS NULL)
)


That whole condition resolves to pd.ID > 0, which is always TRUE unless you have manually added a product with ID of 0



I suspect (p.ID_sSupplier > 0 AND p.ID_sSupplier <> '3') can become just p.ID_sSupplier <> 3 for the same reason



This first condition seems super inclusive too



WHERE (
s.publicChoice=1
OR s.defaultSubject=1
OR s.memberPanCode=''
OR s.memberPanCode IS NULL
)
...


Which leads me to question which rows you are actually trying to avoid with this condition?



That GROUP BY clause is worrisome too, as you have no aggregate columns selected.. a lot of your final columns will be arbitrarily selected



What are you actually trying to achieve with this query?



It's worth remembering that OR conditions tend to be slower to resolve than AND conditions when using queries







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 8 at 16:38









Arth

8,70932145




8,70932145








  • 1




    Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
    – Bostjan
    Nov 8 at 20:11












  • No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
    – Arth
    Nov 12 at 17:17














  • 1




    Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
    – Bostjan
    Nov 8 at 20:11












  • No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
    – Arth
    Nov 12 at 17:17








1




1




Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
– Bostjan
Nov 8 at 20:11






Hi, thank you as well for posting this well thought out answer. I agree the query is a mess as is most of the site...I took over the maintenance of it when it moved servers...I will be optimizing most queries, but like I said in the above answer, I was baffled by the difference between the two DBs. Thank you so much though for the effort.
– Bostjan
Nov 8 at 20:11














No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
– Arth
Nov 12 at 17:17




No problem, happy to help! I understand the bafflement, although it looks like you have some other answers/comments that point towards what may have happened. Although it is interesting from an academic point of view.. if you are optimising the queries anyway, you'll probably end up with a wildly different explain plan on both servers, so an exact answer to the question may end up obsolete!
– Arth
Nov 12 at 17:17











0














The execution plans (show in the EXPLAIN output) are different. So we reasonably expect different performance characteristics.



As @RickJames pointed out in a comment, there seem to be some indexes missing in the target environment.



The question states: "Indexes are the same on both servers."



But the information provided leads us to a conclusion that the indexs are not the same.



We see some indexes referenced in the output of the first EXPLAIN. And those index names are not found in the output of the second EXPLAIN. Those index names are also not found in the schema definition script.





Q: Why are some of the indexes (reported in the first EXPLAIN missing) from the schema definition?



Q: Was the output from mysqldump file for the migration modified to remove some index definitions?



Q: Was some tool other than mysqldump used to extract the schema definition for the migration, and were the indexes were omitted?



Q: Did some "create index" statements fail to execute in the target environment? (Possibly because of limits on sizes of columns in indexes?)





Or maybe I have it the other way around, maybe there are indexes that were added in the target that didn't exist in the source.






share|improve this answer























  • Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
    – Bostjan
    Nov 13 at 7:56
















0














The execution plans (show in the EXPLAIN output) are different. So we reasonably expect different performance characteristics.



As @RickJames pointed out in a comment, there seem to be some indexes missing in the target environment.



The question states: "Indexes are the same on both servers."



But the information provided leads us to a conclusion that the indexs are not the same.



We see some indexes referenced in the output of the first EXPLAIN. And those index names are not found in the output of the second EXPLAIN. Those index names are also not found in the schema definition script.





Q: Why are some of the indexes (reported in the first EXPLAIN missing) from the schema definition?



Q: Was the output from mysqldump file for the migration modified to remove some index definitions?



Q: Was some tool other than mysqldump used to extract the schema definition for the migration, and were the indexes were omitted?



Q: Did some "create index" statements fail to execute in the target environment? (Possibly because of limits on sizes of columns in indexes?)





Or maybe I have it the other way around, maybe there are indexes that were added in the target that didn't exist in the source.






share|improve this answer























  • Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
    – Bostjan
    Nov 13 at 7:56














0












0








0






The execution plans (show in the EXPLAIN output) are different. So we reasonably expect different performance characteristics.



As @RickJames pointed out in a comment, there seem to be some indexes missing in the target environment.



The question states: "Indexes are the same on both servers."



But the information provided leads us to a conclusion that the indexs are not the same.



We see some indexes referenced in the output of the first EXPLAIN. And those index names are not found in the output of the second EXPLAIN. Those index names are also not found in the schema definition script.





Q: Why are some of the indexes (reported in the first EXPLAIN missing) from the schema definition?



Q: Was the output from mysqldump file for the migration modified to remove some index definitions?



Q: Was some tool other than mysqldump used to extract the schema definition for the migration, and were the indexes were omitted?



Q: Did some "create index" statements fail to execute in the target environment? (Possibly because of limits on sizes of columns in indexes?)





Or maybe I have it the other way around, maybe there are indexes that were added in the target that didn't exist in the source.






share|improve this answer














The execution plans (show in the EXPLAIN output) are different. So we reasonably expect different performance characteristics.



As @RickJames pointed out in a comment, there seem to be some indexes missing in the target environment.



The question states: "Indexes are the same on both servers."



But the information provided leads us to a conclusion that the indexs are not the same.



We see some indexes referenced in the output of the first EXPLAIN. And those index names are not found in the output of the second EXPLAIN. Those index names are also not found in the schema definition script.





Q: Why are some of the indexes (reported in the first EXPLAIN missing) from the schema definition?



Q: Was the output from mysqldump file for the migration modified to remove some index definitions?



Q: Was some tool other than mysqldump used to extract the schema definition for the migration, and were the indexes were omitted?



Q: Did some "create index" statements fail to execute in the target environment? (Possibly because of limits on sizes of columns in indexes?)





Or maybe I have it the other way around, maybe there are indexes that were added in the target that didn't exist in the source.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 14:27

























answered Nov 12 at 14:14









spencer7593

84k107792




84k107792












  • Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
    – Bostjan
    Nov 13 at 7:56


















  • Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
    – Bostjan
    Nov 13 at 7:56
















Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
– Bostjan
Nov 13 at 7:56




Hi, yes...there were indexes added in the new, slower environment...I used both HeidiSQL and mysqldump to create DB backups, but both deliver the same abysmal performance
– Bostjan
Nov 13 at 7:56


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


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





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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%2fstackoverflow.com%2fquestions%2f53169118%2fmysql-to-older-mariadb-slower-performance%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

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python