Cant get rid of filesort in simple queryHigh Disk IO, How to mitigate?EXPLAIN output suggests that my index...
How can I differentiate duration vs starting time
Draw triangle with text in vertices/edges
Cryptic cross... with words
Boss asked me to sign a resignation paper without a date on it along with my new contract
What is the smallest molar volume?
Found a major flaw in paper from home university – to which I would like to return
How do I avoid the "chosen hero" feeling?
Why and/or operations in python statement are behaving unexpectedly?
How do I add a strong "onion flavor" to the biryani (in restaurant style)?
Now...where was I?
How bad is a Computer Science course that doesn't teach Design Patterns?
Reduce Reflections
Why don't you get burned by the wood benches in a sauna?
Is there any danger of my neighbor having my wife's signature?
Can I do anything else with aspersions other than cast them?
Can a Hydra make multiple opportunity attacks at once?
Identical projects by students at two different colleges: still plagiarism?
How to transport 10,000 terrestrial trolls across ocean fast?
Why is Shelob considered evil?
What are some good alternatives to Whisper for blockchain messaging?
What's the meaning of #0?
Spells that would be effective against a Modern Day army but would NOT destroy a fantasy one
Exploding Numbers
Checking if an integer permutation is cyclic in Java
Cant get rid of filesort in simple query
High Disk IO, How to mitigate?EXPLAIN output suggests that my index is not being usedFilesort while using primary key for orderbyIdentical query, tables, but different EXPLAIN and performanceWhy does IN (subquery) perform bad when = (subquery) is blazing fast?Deciding which MySQL execution plan is betterOptimizing slow queryOptimizing a simple query on a large tableselect MAX() from MySQL view (2x INNER JOIN) is slowPerformance of mysql equi-join observed in HDD and SSD
I have two tables. One for texts and one to assign those texts to categories. I want to select texts of one specific category and order them by last change date. So, I am using this query:
SELECT
t2.text_id
FROM
texts_to_categories AS t1,
texts AS t2
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10
I tried a lot of index combinations but I keep getting a temporary and filesort:
id select_type table type possible_keys key key_len ref rows extra
1 SIMPLE t1 ref text_id,text_id_2,category_id category_id 5 const 203 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY,text_id PRIMARY 4 text_id 1 Using where
Edit: Here is a CREATE TABLE for the two tables:
CREATE TABLE `texts` (
`text_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`time_changed` datetime DEFAULT NULL,
PRIMARY KEY (`text_id`),
KEY `time_changed` (`time_changed`)
) ENGINE=InnoDB AUTO_INCREMENT=132207 DEFAULT CHARSET=utf8
CREATE TABLE `texts_to_categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`text_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `text_id` (`text_id`,`category_id`),
KEY `text_id_2` (`text_id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=740789 DEFAULT CHARSET=utf8
mysql
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I have two tables. One for texts and one to assign those texts to categories. I want to select texts of one specific category and order them by last change date. So, I am using this query:
SELECT
t2.text_id
FROM
texts_to_categories AS t1,
texts AS t2
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10
I tried a lot of index combinations but I keep getting a temporary and filesort:
id select_type table type possible_keys key key_len ref rows extra
1 SIMPLE t1 ref text_id,text_id_2,category_id category_id 5 const 203 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY,text_id PRIMARY 4 text_id 1 Using where
Edit: Here is a CREATE TABLE for the two tables:
CREATE TABLE `texts` (
`text_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`time_changed` datetime DEFAULT NULL,
PRIMARY KEY (`text_id`),
KEY `time_changed` (`time_changed`)
) ENGINE=InnoDB AUTO_INCREMENT=132207 DEFAULT CHARSET=utf8
CREATE TABLE `texts_to_categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`text_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `text_id` (`text_id`,`category_id`),
KEY `text_id_2` (`text_id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=740789 DEFAULT CHARSET=utf8
mysql
bumped to the homepage by Community♦ 6 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
Can you addshow create table ...
for the two tables? The query plan doesn't seem to use any index.
– Giovanni
Mar 10 '15 at 13:40
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
An index on(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the wholeEXPLAIN
output (and not cut some parts off) so we can see which indexes are used.
– ypercubeᵀᴹ
Mar 11 '15 at 9:00
add a comment |
I have two tables. One for texts and one to assign those texts to categories. I want to select texts of one specific category and order them by last change date. So, I am using this query:
SELECT
t2.text_id
FROM
texts_to_categories AS t1,
texts AS t2
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10
I tried a lot of index combinations but I keep getting a temporary and filesort:
id select_type table type possible_keys key key_len ref rows extra
1 SIMPLE t1 ref text_id,text_id_2,category_id category_id 5 const 203 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY,text_id PRIMARY 4 text_id 1 Using where
Edit: Here is a CREATE TABLE for the two tables:
CREATE TABLE `texts` (
`text_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`time_changed` datetime DEFAULT NULL,
PRIMARY KEY (`text_id`),
KEY `time_changed` (`time_changed`)
) ENGINE=InnoDB AUTO_INCREMENT=132207 DEFAULT CHARSET=utf8
CREATE TABLE `texts_to_categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`text_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `text_id` (`text_id`,`category_id`),
KEY `text_id_2` (`text_id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=740789 DEFAULT CHARSET=utf8
mysql
I have two tables. One for texts and one to assign those texts to categories. I want to select texts of one specific category and order them by last change date. So, I am using this query:
SELECT
t2.text_id
FROM
texts_to_categories AS t1,
texts AS t2
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10
I tried a lot of index combinations but I keep getting a temporary and filesort:
id select_type table type possible_keys key key_len ref rows extra
1 SIMPLE t1 ref text_id,text_id_2,category_id category_id 5 const 203 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY,text_id PRIMARY 4 text_id 1 Using where
Edit: Here is a CREATE TABLE for the two tables:
CREATE TABLE `texts` (
`text_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`time_changed` datetime DEFAULT NULL,
PRIMARY KEY (`text_id`),
KEY `time_changed` (`time_changed`)
) ENGINE=InnoDB AUTO_INCREMENT=132207 DEFAULT CHARSET=utf8
CREATE TABLE `texts_to_categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`text_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `text_id` (`text_id`,`category_id`),
KEY `text_id_2` (`text_id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=740789 DEFAULT CHARSET=utf8
mysql
mysql
edited Mar 11 '15 at 9:30
leoj
asked Mar 10 '15 at 7:07
leojleoj
112
112
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.
Can you addshow create table ...
for the two tables? The query plan doesn't seem to use any index.
– Giovanni
Mar 10 '15 at 13:40
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
An index on(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the wholeEXPLAIN
output (and not cut some parts off) so we can see which indexes are used.
– ypercubeᵀᴹ
Mar 11 '15 at 9:00
add a comment |
Can you addshow create table ...
for the two tables? The query plan doesn't seem to use any index.
– Giovanni
Mar 10 '15 at 13:40
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
An index on(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the wholeEXPLAIN
output (and not cut some parts off) so we can see which indexes are used.
– ypercubeᵀᴹ
Mar 11 '15 at 9:00
Can you add
show create table ...
for the two tables? The query plan doesn't seem to use any index.– Giovanni
Mar 10 '15 at 13:40
Can you add
show create table ...
for the two tables? The query plan doesn't seem to use any index.– Giovanni
Mar 10 '15 at 13:40
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
An index on
(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the whole EXPLAIN
output (and not cut some parts off) so we can see which indexes are used.– ypercubeᵀᴹ
Mar 11 '15 at 9:00
An index on
(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the whole EXPLAIN
output (and not cut some parts off) so we can see which indexes are used.– ypercubeᵀᴹ
Mar 11 '15 at 9:00
add a comment |
1 Answer
1
active
oldest
votes
You can try to add an index on time_changed:
alter table texts add index (time_changed);
this could get rid of Using temporary
and filesort
. But you need to define indexes for your query because the query plan show Using where
instead of more healthy Using index
.
Updated
Maybe the main culprit for the temporary/filesort is the order of the join. It is not good practice to force the optimizer without a good reason, but you could try to force the join order to test if the temporary/filesort goes away. I have swapped the tables and added a straight_join
clause:
SELECT straight_join
t2.text_id
FROM
texts AS t2,
texts_to_categories AS t1
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10;
Let me know what is the query plan of the previous query.
I don't think that temporary/filesort is a big deal for few hundred rows. I would let the optimizer do its job. I would be more worried to get a better tables schema. If it is feasible for you, I suggest the following changes to your schema.
For texts_categories
your table permits NULL value for text_id
and for category_id
. So I would delete NULL values:
delete from texts_to_categories where category_id is NULL or text_id is NULL;
alter table texts_to_categories
change category_id category_id int unsigned not null,
change text_id text_id int unsigned not null;
Next if you don't need texts_categories.id
column, I would get rid of it, and I would reorganize indexes:
alter table texts_to_categories
drop column id,
add primary key category_text (category_id, text_id),
drop index text_id,
drop index category_id,
add index text_id;
For table texts
I will try time_changed
column to do not permit null values:
update texts_bck
set time_changed = '2010-01-01' -- some default
where time_changed is NULL;
alter table texts
change column time_changed time_changed datetime not null
default current_timestamp;
I hope this is of help.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f94832%2fcant-get-rid-of-filesort-in-simple-query%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
You can try to add an index on time_changed:
alter table texts add index (time_changed);
this could get rid of Using temporary
and filesort
. But you need to define indexes for your query because the query plan show Using where
instead of more healthy Using index
.
Updated
Maybe the main culprit for the temporary/filesort is the order of the join. It is not good practice to force the optimizer without a good reason, but you could try to force the join order to test if the temporary/filesort goes away. I have swapped the tables and added a straight_join
clause:
SELECT straight_join
t2.text_id
FROM
texts AS t2,
texts_to_categories AS t1
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10;
Let me know what is the query plan of the previous query.
I don't think that temporary/filesort is a big deal for few hundred rows. I would let the optimizer do its job. I would be more worried to get a better tables schema. If it is feasible for you, I suggest the following changes to your schema.
For texts_categories
your table permits NULL value for text_id
and for category_id
. So I would delete NULL values:
delete from texts_to_categories where category_id is NULL or text_id is NULL;
alter table texts_to_categories
change category_id category_id int unsigned not null,
change text_id text_id int unsigned not null;
Next if you don't need texts_categories.id
column, I would get rid of it, and I would reorganize indexes:
alter table texts_to_categories
drop column id,
add primary key category_text (category_id, text_id),
drop index text_id,
drop index category_id,
add index text_id;
For table texts
I will try time_changed
column to do not permit null values:
update texts_bck
set time_changed = '2010-01-01' -- some default
where time_changed is NULL;
alter table texts
change column time_changed time_changed datetime not null
default current_timestamp;
I hope this is of help.
add a comment |
You can try to add an index on time_changed:
alter table texts add index (time_changed);
this could get rid of Using temporary
and filesort
. But you need to define indexes for your query because the query plan show Using where
instead of more healthy Using index
.
Updated
Maybe the main culprit for the temporary/filesort is the order of the join. It is not good practice to force the optimizer without a good reason, but you could try to force the join order to test if the temporary/filesort goes away. I have swapped the tables and added a straight_join
clause:
SELECT straight_join
t2.text_id
FROM
texts AS t2,
texts_to_categories AS t1
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10;
Let me know what is the query plan of the previous query.
I don't think that temporary/filesort is a big deal for few hundred rows. I would let the optimizer do its job. I would be more worried to get a better tables schema. If it is feasible for you, I suggest the following changes to your schema.
For texts_categories
your table permits NULL value for text_id
and for category_id
. So I would delete NULL values:
delete from texts_to_categories where category_id is NULL or text_id is NULL;
alter table texts_to_categories
change category_id category_id int unsigned not null,
change text_id text_id int unsigned not null;
Next if you don't need texts_categories.id
column, I would get rid of it, and I would reorganize indexes:
alter table texts_to_categories
drop column id,
add primary key category_text (category_id, text_id),
drop index text_id,
drop index category_id,
add index text_id;
For table texts
I will try time_changed
column to do not permit null values:
update texts_bck
set time_changed = '2010-01-01' -- some default
where time_changed is NULL;
alter table texts
change column time_changed time_changed datetime not null
default current_timestamp;
I hope this is of help.
add a comment |
You can try to add an index on time_changed:
alter table texts add index (time_changed);
this could get rid of Using temporary
and filesort
. But you need to define indexes for your query because the query plan show Using where
instead of more healthy Using index
.
Updated
Maybe the main culprit for the temporary/filesort is the order of the join. It is not good practice to force the optimizer without a good reason, but you could try to force the join order to test if the temporary/filesort goes away. I have swapped the tables and added a straight_join
clause:
SELECT straight_join
t2.text_id
FROM
texts AS t2,
texts_to_categories AS t1
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10;
Let me know what is the query plan of the previous query.
I don't think that temporary/filesort is a big deal for few hundred rows. I would let the optimizer do its job. I would be more worried to get a better tables schema. If it is feasible for you, I suggest the following changes to your schema.
For texts_categories
your table permits NULL value for text_id
and for category_id
. So I would delete NULL values:
delete from texts_to_categories where category_id is NULL or text_id is NULL;
alter table texts_to_categories
change category_id category_id int unsigned not null,
change text_id text_id int unsigned not null;
Next if you don't need texts_categories.id
column, I would get rid of it, and I would reorganize indexes:
alter table texts_to_categories
drop column id,
add primary key category_text (category_id, text_id),
drop index text_id,
drop index category_id,
add index text_id;
For table texts
I will try time_changed
column to do not permit null values:
update texts_bck
set time_changed = '2010-01-01' -- some default
where time_changed is NULL;
alter table texts
change column time_changed time_changed datetime not null
default current_timestamp;
I hope this is of help.
You can try to add an index on time_changed:
alter table texts add index (time_changed);
this could get rid of Using temporary
and filesort
. But you need to define indexes for your query because the query plan show Using where
instead of more healthy Using index
.
Updated
Maybe the main culprit for the temporary/filesort is the order of the join. It is not good practice to force the optimizer without a good reason, but you could try to force the join order to test if the temporary/filesort goes away. I have swapped the tables and added a straight_join
clause:
SELECT straight_join
t2.text_id
FROM
texts AS t2,
texts_to_categories AS t1
WHERE
t1.category_id = 123
AND t2.text_id = t1.text_id
ORDER BY
t2.time_changed DESC
LIMIT 10;
Let me know what is the query plan of the previous query.
I don't think that temporary/filesort is a big deal for few hundred rows. I would let the optimizer do its job. I would be more worried to get a better tables schema. If it is feasible for you, I suggest the following changes to your schema.
For texts_categories
your table permits NULL value for text_id
and for category_id
. So I would delete NULL values:
delete from texts_to_categories where category_id is NULL or text_id is NULL;
alter table texts_to_categories
change category_id category_id int unsigned not null,
change text_id text_id int unsigned not null;
Next if you don't need texts_categories.id
column, I would get rid of it, and I would reorganize indexes:
alter table texts_to_categories
drop column id,
add primary key category_text (category_id, text_id),
drop index text_id,
drop index category_id,
add index text_id;
For table texts
I will try time_changed
column to do not permit null values:
update texts_bck
set time_changed = '2010-01-01' -- some default
where time_changed is NULL;
alter table texts
change column time_changed time_changed datetime not null
default current_timestamp;
I hope this is of help.
edited Mar 11 '15 at 13:57
answered Mar 10 '15 at 13:47
GiovanniGiovanni
822514
822514
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f94832%2fcant-get-rid-of-filesort-in-simple-query%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you add
show create table ...
for the two tables? The query plan doesn't seem to use any index.– Giovanni
Mar 10 '15 at 13:40
Okay, I edited my post.
– leoj
Mar 11 '15 at 2:16
An index on
(category_id, text_id)
would help your query more than the ones you have. It would also be good if you provided the wholeEXPLAIN
output (and not cut some parts off) so we can see which indexes are used.– ypercubeᵀᴹ
Mar 11 '15 at 9:00