Substring join or additional table, which is faster?Which is faster joinSQL to select random mix of rows fairlyAltering strings while selecting themSQL Server: CONVERT From ISO8601 To DateTime Within QuerySingle year column and multiple weeks columns into single year/week column with PIVOTSearching multiple tables in SQLTransposing hierachical data from one VARCHAR to two INTsSSRS --> .xlsx file --> SQL ETL — “External table not in expected format” error, but only when files have not been openedHow to Know if I have A Restricted or Full Access to TableHow to store hierarchical dimension for timeseries data
If a person had control of every single cell of their body, would they be able to transform into another creature?
Why do most published works in medical imaging try to reduce false positives?
Where have Brexit voters gone?
How to use " shadow " in pstricks?
Writing with dry erase marker on Shabbos, is it permitted?
Defining the standard model of PA so that a space alien could understand
Simple fuzz pedal using breadboard
In general, would I need to season a meat when making a sauce?
Plot twist where the antagonist wins
What was the idiom for something that we take without a doubt?
Is real public IP Address hidden when using a system wide proxy in Windows 10?
Is neural networks training done one-by-one?
Which is the common name of Mind Flayers?
What is the object moving across the ceiling in this stock footage?
Why do Ryanair allow me to book connecting itineraries through a third party, but not through their own website?
Popcorn is the only acceptable snack to consume while watching a movie
Computing the matrix powers of a non-diagonalizable matrix
Why doesn't the Earth accelerate towards the Moon?
Cipher Block Chaining - How do you change the plaintext of all blocks?
Should breaking down something like a door be adjudicated as an attempt to beat its AC and HP, or as an ability check against a set DC?
How to respond to an upset student?
Should I disclose a colleague's illness (that I should not know) when others badmouth him
When and what was the first 3D acceleration device ever released?
Would jet fuel for an F-16 or F-35 be producible during WW2?
Substring join or additional table, which is faster?
Which is faster joinSQL to select random mix of rows fairlyAltering strings while selecting themSQL Server: CONVERT From ISO8601 To DateTime Within QuerySingle year column and multiple weeks columns into single year/week column with PIVOTSearching multiple tables in SQLTransposing hierachical data from one VARCHAR to two INTsSSRS --> .xlsx file --> SQL ETL — “External table not in expected format” error, but only when files have not been openedHow to Know if I have A Restricted or Full Access to TableHow to store hierarchical dimension for timeseries data
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have a case that come up regularly at work. I have many tables that use a 4 character string as a foreign key : G191
The G
is a sort of category, the 19
is the year, and the 1
is an instance.
Getting all rows of category G
is something we do very often. Usually like:
SELECT * FROM [Table]
WHERE Left([ID], 1) = 'G'
There is a way to get this effect without manipulating a string, by joining to a table where this category is defined:
SELECT * FROM [Table]
JOIN [Categories] ON [Table].CategoryID = [Categories].CategoryID
WHERE [Categories].Letter = 'G'
My co worker insists that the first way is more performant, and rolls his eyes at me for doing it the second way.
Which one is better? Does joining by another table really add more work then checking the first character of a string?
sql-server sql-server-2014
add a comment |
I have a case that come up regularly at work. I have many tables that use a 4 character string as a foreign key : G191
The G
is a sort of category, the 19
is the year, and the 1
is an instance.
Getting all rows of category G
is something we do very often. Usually like:
SELECT * FROM [Table]
WHERE Left([ID], 1) = 'G'
There is a way to get this effect without manipulating a string, by joining to a table where this category is defined:
SELECT * FROM [Table]
JOIN [Categories] ON [Table].CategoryID = [Categories].CategoryID
WHERE [Categories].Letter = 'G'
My co worker insists that the first way is more performant, and rolls his eyes at me for doing it the second way.
Which one is better? Does joining by another table really add more work then checking the first character of a string?
sql-server sql-server-2014
4
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42
add a comment |
I have a case that come up regularly at work. I have many tables that use a 4 character string as a foreign key : G191
The G
is a sort of category, the 19
is the year, and the 1
is an instance.
Getting all rows of category G
is something we do very often. Usually like:
SELECT * FROM [Table]
WHERE Left([ID], 1) = 'G'
There is a way to get this effect without manipulating a string, by joining to a table where this category is defined:
SELECT * FROM [Table]
JOIN [Categories] ON [Table].CategoryID = [Categories].CategoryID
WHERE [Categories].Letter = 'G'
My co worker insists that the first way is more performant, and rolls his eyes at me for doing it the second way.
Which one is better? Does joining by another table really add more work then checking the first character of a string?
sql-server sql-server-2014
I have a case that come up regularly at work. I have many tables that use a 4 character string as a foreign key : G191
The G
is a sort of category, the 19
is the year, and the 1
is an instance.
Getting all rows of category G
is something we do very often. Usually like:
SELECT * FROM [Table]
WHERE Left([ID], 1) = 'G'
There is a way to get this effect without manipulating a string, by joining to a table where this category is defined:
SELECT * FROM [Table]
JOIN [Categories] ON [Table].CategoryID = [Categories].CategoryID
WHERE [Categories].Letter = 'G'
My co worker insists that the first way is more performant, and rolls his eyes at me for doing it the second way.
Which one is better? Does joining by another table really add more work then checking the first character of a string?
sql-server sql-server-2014
sql-server sql-server-2014
asked May 13 at 17:09
SpeedOfRoundSpeedOfRound
1363
1363
4
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42
add a comment |
4
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42
4
4
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42
add a comment |
1 Answer
1
active
oldest
votes
Why Yours Is Better
In general, your pattern is a better idea.
Performance will depend on indexes, predicate selectivity, and table size though.
The reason your pattern is a better idea comes down to the concept of SARGability, which is a fancy word for if your search arguments can be used as seek predicates, or even fully pushed predicates, (i.e. not being processed in Filter operators after accessing an index).
Some examples of where this can hurt in joins and where clauses are:
- function(column) = something
- column + column = something
- column + value = something
- column = @something or @something IS NULL
- column like ‘%something%’
- column = case when …
When you do stuff like this, your queries can end up with all sorts of bad side effects:
- Increased CPU (burn baby burn)
- Index Scans (when you could have Seeks)
- Implicit Conversion (if your predicates produce a different data type)
- Poor Cardinality Estimates (poking the optimizer in the eye)
- Inappropriate Plan Choices (because the optimizer is blind now, you jerk)
- Long Running Queries (yay job security!)
Better Options
SARGable options for what you're looking for would include:
WHERE [ID] LIKE 'G%'
or
WHERE [ID] >= 'G' AND [ID] < 'H'
An alternative solution would be to add a computed column in just the table you're searching:
ALTER TABLE [Table]
ADD Lefty AS Left([ID], 1);
CREATE INDEX ix_whatever
ON [Table] (CategoryID , Lefty);
Though like I said before, the performance difference may not be dramatic with smaller tables.
It's also possible that this index won't be used since your example query is selecting all of the table columns, and this index doesn't cover them. But that's a story for a different day.
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%2f238042%2fsubstring-join-or-additional-table-which-is-faster%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
Why Yours Is Better
In general, your pattern is a better idea.
Performance will depend on indexes, predicate selectivity, and table size though.
The reason your pattern is a better idea comes down to the concept of SARGability, which is a fancy word for if your search arguments can be used as seek predicates, or even fully pushed predicates, (i.e. not being processed in Filter operators after accessing an index).
Some examples of where this can hurt in joins and where clauses are:
- function(column) = something
- column + column = something
- column + value = something
- column = @something or @something IS NULL
- column like ‘%something%’
- column = case when …
When you do stuff like this, your queries can end up with all sorts of bad side effects:
- Increased CPU (burn baby burn)
- Index Scans (when you could have Seeks)
- Implicit Conversion (if your predicates produce a different data type)
- Poor Cardinality Estimates (poking the optimizer in the eye)
- Inappropriate Plan Choices (because the optimizer is blind now, you jerk)
- Long Running Queries (yay job security!)
Better Options
SARGable options for what you're looking for would include:
WHERE [ID] LIKE 'G%'
or
WHERE [ID] >= 'G' AND [ID] < 'H'
An alternative solution would be to add a computed column in just the table you're searching:
ALTER TABLE [Table]
ADD Lefty AS Left([ID], 1);
CREATE INDEX ix_whatever
ON [Table] (CategoryID , Lefty);
Though like I said before, the performance difference may not be dramatic with smaller tables.
It's also possible that this index won't be used since your example query is selecting all of the table columns, and this index doesn't cover them. But that's a story for a different day.
add a comment |
Why Yours Is Better
In general, your pattern is a better idea.
Performance will depend on indexes, predicate selectivity, and table size though.
The reason your pattern is a better idea comes down to the concept of SARGability, which is a fancy word for if your search arguments can be used as seek predicates, or even fully pushed predicates, (i.e. not being processed in Filter operators after accessing an index).
Some examples of where this can hurt in joins and where clauses are:
- function(column) = something
- column + column = something
- column + value = something
- column = @something or @something IS NULL
- column like ‘%something%’
- column = case when …
When you do stuff like this, your queries can end up with all sorts of bad side effects:
- Increased CPU (burn baby burn)
- Index Scans (when you could have Seeks)
- Implicit Conversion (if your predicates produce a different data type)
- Poor Cardinality Estimates (poking the optimizer in the eye)
- Inappropriate Plan Choices (because the optimizer is blind now, you jerk)
- Long Running Queries (yay job security!)
Better Options
SARGable options for what you're looking for would include:
WHERE [ID] LIKE 'G%'
or
WHERE [ID] >= 'G' AND [ID] < 'H'
An alternative solution would be to add a computed column in just the table you're searching:
ALTER TABLE [Table]
ADD Lefty AS Left([ID], 1);
CREATE INDEX ix_whatever
ON [Table] (CategoryID , Lefty);
Though like I said before, the performance difference may not be dramatic with smaller tables.
It's also possible that this index won't be used since your example query is selecting all of the table columns, and this index doesn't cover them. But that's a story for a different day.
add a comment |
Why Yours Is Better
In general, your pattern is a better idea.
Performance will depend on indexes, predicate selectivity, and table size though.
The reason your pattern is a better idea comes down to the concept of SARGability, which is a fancy word for if your search arguments can be used as seek predicates, or even fully pushed predicates, (i.e. not being processed in Filter operators after accessing an index).
Some examples of where this can hurt in joins and where clauses are:
- function(column) = something
- column + column = something
- column + value = something
- column = @something or @something IS NULL
- column like ‘%something%’
- column = case when …
When you do stuff like this, your queries can end up with all sorts of bad side effects:
- Increased CPU (burn baby burn)
- Index Scans (when you could have Seeks)
- Implicit Conversion (if your predicates produce a different data type)
- Poor Cardinality Estimates (poking the optimizer in the eye)
- Inappropriate Plan Choices (because the optimizer is blind now, you jerk)
- Long Running Queries (yay job security!)
Better Options
SARGable options for what you're looking for would include:
WHERE [ID] LIKE 'G%'
or
WHERE [ID] >= 'G' AND [ID] < 'H'
An alternative solution would be to add a computed column in just the table you're searching:
ALTER TABLE [Table]
ADD Lefty AS Left([ID], 1);
CREATE INDEX ix_whatever
ON [Table] (CategoryID , Lefty);
Though like I said before, the performance difference may not be dramatic with smaller tables.
It's also possible that this index won't be used since your example query is selecting all of the table columns, and this index doesn't cover them. But that's a story for a different day.
Why Yours Is Better
In general, your pattern is a better idea.
Performance will depend on indexes, predicate selectivity, and table size though.
The reason your pattern is a better idea comes down to the concept of SARGability, which is a fancy word for if your search arguments can be used as seek predicates, or even fully pushed predicates, (i.e. not being processed in Filter operators after accessing an index).
Some examples of where this can hurt in joins and where clauses are:
- function(column) = something
- column + column = something
- column + value = something
- column = @something or @something IS NULL
- column like ‘%something%’
- column = case when …
When you do stuff like this, your queries can end up with all sorts of bad side effects:
- Increased CPU (burn baby burn)
- Index Scans (when you could have Seeks)
- Implicit Conversion (if your predicates produce a different data type)
- Poor Cardinality Estimates (poking the optimizer in the eye)
- Inappropriate Plan Choices (because the optimizer is blind now, you jerk)
- Long Running Queries (yay job security!)
Better Options
SARGable options for what you're looking for would include:
WHERE [ID] LIKE 'G%'
or
WHERE [ID] >= 'G' AND [ID] < 'H'
An alternative solution would be to add a computed column in just the table you're searching:
ALTER TABLE [Table]
ADD Lefty AS Left([ID], 1);
CREATE INDEX ix_whatever
ON [Table] (CategoryID , Lefty);
Though like I said before, the performance difference may not be dramatic with smaller tables.
It's also possible that this index won't be used since your example query is selecting all of the table columns, and this index doesn't cover them. But that's a story for a different day.
edited May 13 at 21:29
answered May 13 at 17:38
Erik DarlingErik Darling
23.6k1374118
23.6k1374118
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%2f238042%2fsubstring-join-or-additional-table-which-is-faster%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
4
Have you tried comparing actual run times of both queries? If not, why?
– mustaccio
May 13 at 18:42