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
Addressing an email
How was the blinking terminal cursor invented?
How to plot a surface from a system of equations?
Would it be possible to set up a franchise in the ancient world?
How can I prevent Bash expansion from passing files starting with "-" as argument?
Cycling to work - 30 mile return
What were the "pills" that were added to solid waste in Apollo 7?
Why didn't Daenerys' advisers suggest assassinating Cersei?
Why does string strummed with finger sound different from the one strummed with pick?
Why would Thor need to strike a building with lightning to attack enemies?
What city and town structures are important in a low fantasy medieval world?
FIFO data structure in pure C
Warped chessboard
Will this series of events work to drown the Tarrasque?
What does it mean for a program to be 32 or 64 bit?
What should I wear to go and sign an employment contract?
Why does the U.S military use mercenaries?
Head-internal relative clauses
Should I twist DC power and ground wires from a power supply?
Bash - Execute two commands and get exit status 1 if first fails
On a piano, are the effects of holding notes and the sustain pedal the same for a single chord?
What does this 'x' mean on the stem of the voice's note, above the notehead?
Are there any crystals that are theoretically possible, but haven't yet been made?
Windows reverting changes made by Linux to FAT32 partition
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
New contributor
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
New contributor
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
New contributor
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
New contributor
New contributor
New contributor
asked May 13 at 17:09
SpeedOfRoundSpeedOfRound
1363
1363
New contributor
New contributor
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
);
);
SpeedOfRound is a new contributor. Be nice, and check out our Code of Conduct.
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.6k1373117
23.6k1373117
add a comment |
add a comment |
SpeedOfRound is a new contributor. Be nice, and check out our Code of Conduct.
SpeedOfRound is a new contributor. Be nice, and check out our Code of Conduct.
SpeedOfRound is a new contributor. Be nice, and check out our Code of Conduct.
SpeedOfRound is a new contributor. Be nice, and check out our Code of Conduct.
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