Covering index used despite missing columnInnoDB - Use combined index with primary key on GROUP BYMust an index cover all selected columns for it to be used for ORDER BY?Proper Index for WHERE X <> 1 AND Y <> 1 ORDER BY ZIs index on foreign key used? (No difference in EXPLAIN.)Awful execution plans after migrating from MySQL 5.5.11 to MariaDB 5.5.41MySQL query WHERE IN + ORDER BY, which EXPLAIN is better and how to avoid filesort?MySQL Query causing high CPU and taking forever to executeWhy is a query with a join and limit clause running so slow, even using a covering index?Do we need index on “order by” if the “where” clause alreday have index ( small data set )Primary index is being used, not the one which is on the field present in the where condition
What does this Swiss black on yellow rectangular traffic sign with a symbol looking like a dart mean?
Intuition for the role of diffeomorphisms
Can the pre-order traversal of two different trees be the same even though they are different?
What does it cost to buy a tavern?
Drawing a second weapon as part of an attack?
Encounter design and XP thresholds
Is it illegal to withhold someone's passport and green card in California?
Umlaut character order when sorting
How long did the SR-71 take to get to cruising altitude?
Novel in which alien (Martian?) is trapped on Earth in prehistory
"Correct me if I'm wrong"
Has a life raft ever been successfully deployed on a modern commercial flight?
Why is "Congress shall have power to enforce this article by appropriate legislation" necessary?
What triggered jesuits' ban on infinitesimals in 1632?
Why isn't my calculation that we should be able to see the sun well beyond the observable universe valid?
Non-misogynistic way to say “asshole”?
What mathematical theory is required for high frequency trading?
Why is oilcloth made with linseed oil?
Why does Linux list NVMe drives as /dev/nvme0 instead of /dev/sda?
How do I see debug logs for Change Data Capture triggers in Salesforce?
Do I have to explain the mechanical superiority of the player-character within the fiction of the game?
Print one file per line using echo
How does DC work with natural 20?
Counterfeit checks were created for my account. How does this type of fraud work?
Covering index used despite missing column
InnoDB - Use combined index with primary key on GROUP BYMust an index cover all selected columns for it to be used for ORDER BY?Proper Index for WHERE X <> 1 AND Y <> 1 ORDER BY ZIs index on foreign key used? (No difference in EXPLAIN.)Awful execution plans after migrating from MySQL 5.5.11 to MariaDB 5.5.41MySQL query WHERE IN + ORDER BY, which EXPLAIN is better and how to avoid filesort?MySQL Query causing high CPU and taking forever to executeWhy is a query with a join and limit clause running so slow, even using a covering index?Do we need index on “order by” if the “where” clause alreday have index ( small data set )Primary index is being used, not the one which is on the field present in the where condition
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have the following query, using MariaDB 10 / InnoDB:
SELECT id, sender_id, receiver_id, thread_id, date_created, content
FROM user_message
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
This query fetches messages according to the given conditions and sorts by date created.
I have a covering index over (thread_id, date_created)
.
When running EXPLAIN, the correct index is used and I get the output "Using where", although the query is using a column in the middle of the statement that is not in the index. I can use any value for "placeholder = x" and the result is the same.
If I change the sorting to use another column, the EXPLAIN correctly indicates "Using where. Using filesort."
I'm having a head-scratching moment. Could anyone please shed light on this? What I would expect to see is that an additional filesort would be needed as the covering index could not be completed used due to the additional column.
index innodb mariadb covering-index
add a comment |
I have the following query, using MariaDB 10 / InnoDB:
SELECT id, sender_id, receiver_id, thread_id, date_created, content
FROM user_message
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
This query fetches messages according to the given conditions and sorts by date created.
I have a covering index over (thread_id, date_created)
.
When running EXPLAIN, the correct index is used and I get the output "Using where", although the query is using a column in the middle of the statement that is not in the index. I can use any value for "placeholder = x" and the result is the same.
If I change the sorting to use another column, the EXPLAIN correctly indicates "Using where. Using filesort."
I'm having a head-scratching moment. Could anyone please shed light on this? What I would expect to see is that an additional filesort would be needed as the covering index could not be completed used due to the additional column.
index innodb mariadb covering-index
add a comment |
I have the following query, using MariaDB 10 / InnoDB:
SELECT id, sender_id, receiver_id, thread_id, date_created, content
FROM user_message
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
This query fetches messages according to the given conditions and sorts by date created.
I have a covering index over (thread_id, date_created)
.
When running EXPLAIN, the correct index is used and I get the output "Using where", although the query is using a column in the middle of the statement that is not in the index. I can use any value for "placeholder = x" and the result is the same.
If I change the sorting to use another column, the EXPLAIN correctly indicates "Using where. Using filesort."
I'm having a head-scratching moment. Could anyone please shed light on this? What I would expect to see is that an additional filesort would be needed as the covering index could not be completed used due to the additional column.
index innodb mariadb covering-index
I have the following query, using MariaDB 10 / InnoDB:
SELECT id, sender_id, receiver_id, thread_id, date_created, content
FROM user_message
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
This query fetches messages according to the given conditions and sorts by date created.
I have a covering index over (thread_id, date_created)
.
When running EXPLAIN, the correct index is used and I get the output "Using where", although the query is using a column in the middle of the statement that is not in the index. I can use any value for "placeholder = x" and the result is the same.
If I change the sorting to use another column, the EXPLAIN correctly indicates "Using where. Using filesort."
I'm having a head-scratching moment. Could anyone please shed light on this? What I would expect to see is that an additional filesort would be needed as the covering index could not be completed used due to the additional column.
index innodb mariadb covering-index
index innodb mariadb covering-index
asked 11 hours ago
TomTom
1304
1304
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Case A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No problem there, right? If the index is used (to partially match the WHERE
condition), we still need a sort operation to order the results by some_column
(which is not in the index). We also need an extra check (Using Where) to keep only the rows that match the 2nd condition, too. OK.
Case B (the question)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
So, why does it not need a sort here? Because the index is enough to sort as the query wants. There is of course the additional problem of the extra condition (AND placeholder = FALSE
) which is not covered by the index.
OK but we don't really need a sort here. The index can provide us with results that match the first condition (WHERE thread_id = 12345
) and are in the wanted order for output. The only additional check we need - and what the plan does - is to get the rows from the table, in the order provided by the index, and check this 2nd condition until we get 20 matches. That's what the **Using Where"" means.
We may get the 20 matches in the first 20 rows (so really good and fast) or in the first 100 (still likely fast enough) or in the first 1000000 (probably very, very slow) or we may get just 19 matches from the table even after reading all the matching rows from the index (really very slow on a big table). It all depends on the distribution of data.
Case C (even better plan)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Now our index matches both conditions and the order by. The plan is pretty simple: get the first* 20 matches from the index and read the corresponding rows from the table. No extra check (No "Using Where") and no sort (no "Using filesort") needed.
first*: the first 20 when reading the index backwards from the end (as we have ORDER BY .. DESC
) but that's not a problem. B-tree indexes can be read forwards and backwards with almost equal performance.
Thank you - this is a great explanation.
– Tom
11 hours ago
add a comment |
Using index indicates a "Covering index" -- All the columns anywhere in theSELECT
are anywhere in the one index. So, you do not have a "covering" index. And it is not practical to make a covering index for your query (too many columns mentioned).
Using where -- mostly noise.
Using filesort -- The query needs a sort, but it might be in RAM or in a temp table. And there may be multiple sorts (eg,GROUP BY x ORDER BY b
)Either of these will make it possible to look only at 20 rows; any other index will require more rows be touched, possibly the entire table:
INDEX(thread_id, placeholder, date_created)
INDEX(placeholder, thread_id, date_created)No, the cardinality of the components of a composite index does not matter when ordering the columns in the index.
My Cookbook explains how to derive the optimal index, given a SELECT
.
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%2f240742%2fcovering-index-used-despite-missing-column%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Case A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No problem there, right? If the index is used (to partially match the WHERE
condition), we still need a sort operation to order the results by some_column
(which is not in the index). We also need an extra check (Using Where) to keep only the rows that match the 2nd condition, too. OK.
Case B (the question)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
So, why does it not need a sort here? Because the index is enough to sort as the query wants. There is of course the additional problem of the extra condition (AND placeholder = FALSE
) which is not covered by the index.
OK but we don't really need a sort here. The index can provide us with results that match the first condition (WHERE thread_id = 12345
) and are in the wanted order for output. The only additional check we need - and what the plan does - is to get the rows from the table, in the order provided by the index, and check this 2nd condition until we get 20 matches. That's what the **Using Where"" means.
We may get the 20 matches in the first 20 rows (so really good and fast) or in the first 100 (still likely fast enough) or in the first 1000000 (probably very, very slow) or we may get just 19 matches from the table even after reading all the matching rows from the index (really very slow on a big table). It all depends on the distribution of data.
Case C (even better plan)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Now our index matches both conditions and the order by. The plan is pretty simple: get the first* 20 matches from the index and read the corresponding rows from the table. No extra check (No "Using Where") and no sort (no "Using filesort") needed.
first*: the first 20 when reading the index backwards from the end (as we have ORDER BY .. DESC
) but that's not a problem. B-tree indexes can be read forwards and backwards with almost equal performance.
Thank you - this is a great explanation.
– Tom
11 hours ago
add a comment |
Case A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No problem there, right? If the index is used (to partially match the WHERE
condition), we still need a sort operation to order the results by some_column
(which is not in the index). We also need an extra check (Using Where) to keep only the rows that match the 2nd condition, too. OK.
Case B (the question)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
So, why does it not need a sort here? Because the index is enough to sort as the query wants. There is of course the additional problem of the extra condition (AND placeholder = FALSE
) which is not covered by the index.
OK but we don't really need a sort here. The index can provide us with results that match the first condition (WHERE thread_id = 12345
) and are in the wanted order for output. The only additional check we need - and what the plan does - is to get the rows from the table, in the order provided by the index, and check this 2nd condition until we get 20 matches. That's what the **Using Where"" means.
We may get the 20 matches in the first 20 rows (so really good and fast) or in the first 100 (still likely fast enough) or in the first 1000000 (probably very, very slow) or we may get just 19 matches from the table even after reading all the matching rows from the index (really very slow on a big table). It all depends on the distribution of data.
Case C (even better plan)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Now our index matches both conditions and the order by. The plan is pretty simple: get the first* 20 matches from the index and read the corresponding rows from the table. No extra check (No "Using Where") and no sort (no "Using filesort") needed.
first*: the first 20 when reading the index backwards from the end (as we have ORDER BY .. DESC
) but that's not a problem. B-tree indexes can be read forwards and backwards with almost equal performance.
Thank you - this is a great explanation.
– Tom
11 hours ago
add a comment |
Case A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No problem there, right? If the index is used (to partially match the WHERE
condition), we still need a sort operation to order the results by some_column
(which is not in the index). We also need an extra check (Using Where) to keep only the rows that match the 2nd condition, too. OK.
Case B (the question)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
So, why does it not need a sort here? Because the index is enough to sort as the query wants. There is of course the additional problem of the extra condition (AND placeholder = FALSE
) which is not covered by the index.
OK but we don't really need a sort here. The index can provide us with results that match the first condition (WHERE thread_id = 12345
) and are in the wanted order for output. The only additional check we need - and what the plan does - is to get the rows from the table, in the order provided by the index, and check this 2nd condition until we get 20 matches. That's what the **Using Where"" means.
We may get the 20 matches in the first 20 rows (so really good and fast) or in the first 100 (still likely fast enough) or in the first 1000000 (probably very, very slow) or we may get just 19 matches from the table even after reading all the matching rows from the index (really very slow on a big table). It all depends on the distribution of data.
Case C (even better plan)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Now our index matches both conditions and the order by. The plan is pretty simple: get the first* 20 matches from the index and read the corresponding rows from the table. No extra check (No "Using Where") and no sort (no "Using filesort") needed.
first*: the first 20 when reading the index backwards from the end (as we have ORDER BY .. DESC
) but that's not a problem. B-tree indexes can be read forwards and backwards with almost equal performance.
Case A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No problem there, right? If the index is used (to partially match the WHERE
condition), we still need a sort operation to order the results by some_column
(which is not in the index). We also need an extra check (Using Where) to keep only the rows that match the 2nd condition, too. OK.
Case B (the question)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
So, why does it not need a sort here? Because the index is enough to sort as the query wants. There is of course the additional problem of the extra condition (AND placeholder = FALSE
) which is not covered by the index.
OK but we don't really need a sort here. The index can provide us with results that match the first condition (WHERE thread_id = 12345
) and are in the wanted order for output. The only additional check we need - and what the plan does - is to get the rows from the table, in the order provided by the index, and check this 2nd condition until we get 20 matches. That's what the **Using Where"" means.
We may get the 20 matches in the first 20 rows (so really good and fast) or in the first 100 (still likely fast enough) or in the first 1000000 (probably very, very slow) or we may get just 19 matches from the table even after reading all the matching rows from the index (really very slow on a big table). It all depends on the distribution of data.
Case C (even better plan)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Now our index matches both conditions and the order by. The plan is pretty simple: get the first* 20 matches from the index and read the corresponding rows from the table. No extra check (No "Using Where") and no sort (no "Using filesort") needed.
first*: the first 20 when reading the index backwards from the end (as we have ORDER BY .. DESC
) but that's not a problem. B-tree indexes can be read forwards and backwards with almost equal performance.
edited 10 hours ago
answered 11 hours ago


ypercubeᵀᴹypercubeᵀᴹ
79.4k11138225
79.4k11138225
Thank you - this is a great explanation.
– Tom
11 hours ago
add a comment |
Thank you - this is a great explanation.
– Tom
11 hours ago
Thank you - this is a great explanation.
– Tom
11 hours ago
Thank you - this is a great explanation.
– Tom
11 hours ago
add a comment |
Using index indicates a "Covering index" -- All the columns anywhere in theSELECT
are anywhere in the one index. So, you do not have a "covering" index. And it is not practical to make a covering index for your query (too many columns mentioned).
Using where -- mostly noise.
Using filesort -- The query needs a sort, but it might be in RAM or in a temp table. And there may be multiple sorts (eg,GROUP BY x ORDER BY b
)Either of these will make it possible to look only at 20 rows; any other index will require more rows be touched, possibly the entire table:
INDEX(thread_id, placeholder, date_created)
INDEX(placeholder, thread_id, date_created)No, the cardinality of the components of a composite index does not matter when ordering the columns in the index.
My Cookbook explains how to derive the optimal index, given a SELECT
.
add a comment |
Using index indicates a "Covering index" -- All the columns anywhere in theSELECT
are anywhere in the one index. So, you do not have a "covering" index. And it is not practical to make a covering index for your query (too many columns mentioned).
Using where -- mostly noise.
Using filesort -- The query needs a sort, but it might be in RAM or in a temp table. And there may be multiple sorts (eg,GROUP BY x ORDER BY b
)Either of these will make it possible to look only at 20 rows; any other index will require more rows be touched, possibly the entire table:
INDEX(thread_id, placeholder, date_created)
INDEX(placeholder, thread_id, date_created)No, the cardinality of the components of a composite index does not matter when ordering the columns in the index.
My Cookbook explains how to derive the optimal index, given a SELECT
.
add a comment |
Using index indicates a "Covering index" -- All the columns anywhere in theSELECT
are anywhere in the one index. So, you do not have a "covering" index. And it is not practical to make a covering index for your query (too many columns mentioned).
Using where -- mostly noise.
Using filesort -- The query needs a sort, but it might be in RAM or in a temp table. And there may be multiple sorts (eg,GROUP BY x ORDER BY b
)Either of these will make it possible to look only at 20 rows; any other index will require more rows be touched, possibly the entire table:
INDEX(thread_id, placeholder, date_created)
INDEX(placeholder, thread_id, date_created)No, the cardinality of the components of a composite index does not matter when ordering the columns in the index.
My Cookbook explains how to derive the optimal index, given a SELECT
.
Using index indicates a "Covering index" -- All the columns anywhere in theSELECT
are anywhere in the one index. So, you do not have a "covering" index. And it is not practical to make a covering index for your query (too many columns mentioned).
Using where -- mostly noise.
Using filesort -- The query needs a sort, but it might be in RAM or in a temp table. And there may be multiple sorts (eg,GROUP BY x ORDER BY b
)Either of these will make it possible to look only at 20 rows; any other index will require more rows be touched, possibly the entire table:
INDEX(thread_id, placeholder, date_created)
INDEX(placeholder, thread_id, date_created)No, the cardinality of the components of a composite index does not matter when ordering the columns in the index.
My Cookbook explains how to derive the optimal index, given a SELECT
.
answered 9 hours ago
Rick JamesRick James
44.9k22462
44.9k22462
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%2f240742%2fcovering-index-used-despite-missing-column%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