For similar problems I'm used to two solutions, depending on your needs, mainly on performaces or resources or concurrency.. etc etc..
The LIKE
operator could be your best friend also with very big tables.
Indexing
First of all, you need to index your url column, working with 20+ millions records it is not easy task,
indexing it could cost you 1.5 - 2.0 Gb of disk space,
but you will get your query in NO TIME (milliseconds)
With the index on the column to search, LIKE FixedPattern+%
is performed with an index seek, you cannot improve it any further.
First solution:
CREATE NONCLUSTERED INDEX [IX_URL] ON [url_table] ([url]);
DECLARE @Domain VARCHAR(100) = 'https://mywebsite.domain.com/'
DECLARE @Path VARCHAR(100) = 'as/product/'
DECLARE @Product VARCHAR(20) = '4'
DECLARE @LikeAll VARCHAR(100) = @Domain + @Path + @Product + '/%'
SELECT url
FROM url_table
WHERE url LIKE @LikeAll
Second solution
The second option is a bit tricky but very effective.
You said protocol and domain of url are fixed and you need to search for something after.
The following is a technique, you can fine tune it to match your needs.
The idea is to add a virtual (computed) column to your url table and then to add an index on it.
This will greatly reduce index dimensions and improve query performances at the cost of a very little overhead of computing in insert/update
ALTER TABLE url_table ADD path AS (SUBSTRING(url, 30, 4000));
CREATE NONCLUSTERED INDEX [IX_PATH] ON [url_table] ([path]);
DECLARE @Domain VARCHAR(100) = 'https://mywebsite.domain.com/'
DECLARE @Path VARCHAR(100) = 'as/product/'
DECLARE @Product VARCHAR(20) = '4'
DECLARE @LikeMid VARCHAR(100) = @Path + @Product + '/%'
select @Domain + _path -- pay attention!!
FROM url_table
WHERE url LIKE @SrcAll
Please take note, we are selecting @Domain + _path instead of url, to avoid table access and work only on index data.
If you need other columns in url_table your best option is
declare @l table (id int primary key)
insert into @l
select id
from url_table
where _path like @LikeMid
select url
from url_table
where id in (select id from @l)
very fast
Third solution
This is a variant of second one.
In your example data I see the path contains /product/
followed by a number and I'm assuming it as the product number.
Maybe you can consider the following
ALTER TABLE url_table ADD _product AS (cast(substring(url,nullif(CHARINDEX('/product/',url,29)+9,9), CHARINDEX('/',url,nullif(CHARINDEX('/product/',url,29)+9,9))-nullif(CHARINDEX('/product/',url,29)+9,9)) as bigint));
CREATE NONCLUSTERED INDEX [IX_PRODUCT] ON [url] ([_product]);
select id, url
from url_table
where _product = 4
This will produce a computed column with product number of type integer, the index will be only 500Mb and queries on integers will be super fast.
Also the overhead to select all columns from url_table is very very little so you can SELECT *
with almost no performances issues.
P.S.
You can drop your FullText index and save space and resources..
https://mywebsite.domain.com/as/product/
or at least withhttps://mywebsite.domain.com
? – Engdahl/as/product
is always present? or could be different? – Engdahl