patternsqlMinor
Retreive data from two tables of the same structure
Viewed 0 times
tablesthesametwostructureretreivefromdata
Problem
I have a SQLite database where I fetch data from two tables with the following query.
Is this the best and most efficient way? I have stored alarm objects in the database. So there can easily be more than 1 million entries.
select ie.*
from (select *
from History where Station = @station and TimeStampCome = @from
union all
select *
from Pending where Station = @station and TimeStampCome = @from
) ie
order by TimeStampCome desc LIMIT 100 OFFSET 1Is this the best and most efficient way? I have stored alarm objects in the database. So there can easily be more than 1 million entries.
Solution
The outer-level ORDER BY will probably cause the entire combined row set to be sorted – at least to the extent that will enable the server to find the last 100
I would try reducing the combined set by applying a LIMIT to each leg of the UNION ALL query. Note that an ORDER BY cannot be applied directly to an individual SELECT that is a UNION leg. You will have to use more nesting – either a derived table or a CTE – to apply the ORDER BY and then select from that derived table/CTE. Here is a derived table solution:
And this is a variation that uses CTEs, if you are using a SQLite version that supports Common Table Expressions:
Each individual SELECT is using
TimeStampCome entries starting from the penultimate one. Sorting a million entries cannot be cheap, of course.I would try reducing the combined set by applying a LIMIT to each leg of the UNION ALL query. Note that an ORDER BY cannot be applied directly to an individual SELECT that is a UNION leg. You will have to use more nesting – either a derived table or a CTE – to apply the ORDER BY and then select from that derived table/CTE. Here is a derived table solution:
SELECT
ie.*
FROM
(
SELECT
*
FROM
(
SELECT
*
FROM
History
WHERE
Station = @station
AND TimeStampCome = @from
ORDER BY
TimeStampCome DESC
LIMIT 101
) AS s
UNION ALL
SELECT
*
FROM
(
SELECT
*
FROM
Pending
WHERE
Station = @station
AND TimeStampCome = @from
ORDER BY
TimeStampCome DESC
LIMIT 101
) AS s
) AS ie
ORDER BY
TimeStampCome DESC
LIMIT 100
OFFSET 1
;And this is a variation that uses CTEs, if you are using a SQLite version that supports Common Table Expressions:
WITH
HistoryFiltered AS
(
SELECT
*
FROM
History
WHERE
Station = @station
AND TimeStampCome = @from
ORDER BY
TimeStampCome DESC
LIMIT 101
),
PendingFiltered AS
(
SELECT
*
FROM
Pending
WHERE
Station = @station
AND TimeStampCome = @from
ORDER BY
TimeStampCome DESC
LIMIT 101
)
SELECT
ie.*
FROM
(
SELECT * FROM HistoryFiltered
UNION ALL
SELECT * FROM PendingFiltered
) AS ie
ORDER BY
TimeStampCome DESC
LIMIT 100
OFFSET 1
;Each individual SELECT is using
LIMIT 101 rather than LIMIT 100, because at first it is unknown which of them will end up having the latest TimeStampCome entry that will be omitted by the outer OFFSET 1. Therefore, each source row set must provide as much data as necessary for the ultimate SELECT.Code Snippets
SELECT
ie.*
FROM
(
SELECT
*
FROM
(
SELECT
*
FROM
History
WHERE
Station = @station
AND TimeStampCome <= @till
AND TimeStampCome >= @from
ORDER BY
TimeStampCome DESC
LIMIT 101
) AS s
UNION ALL
SELECT
*
FROM
(
SELECT
*
FROM
Pending
WHERE
Station = @station
AND TimeStampCome <= @till
AND TimeStampCome >= @from
ORDER BY
TimeStampCome DESC
LIMIT 101
) AS s
) AS ie
ORDER BY
TimeStampCome DESC
LIMIT 100
OFFSET 1
;WITH
HistoryFiltered AS
(
SELECT
*
FROM
History
WHERE
Station = @station
AND TimeStampCome <= @till
AND TimeStampCome >= @from
ORDER BY
TimeStampCome DESC
LIMIT 101
),
PendingFiltered AS
(
SELECT
*
FROM
Pending
WHERE
Station = @station
AND TimeStampCome <= @till
AND TimeStampCome >= @from
ORDER BY
TimeStampCome DESC
LIMIT 101
)
SELECT
ie.*
FROM
(
SELECT * FROM HistoryFiltered
UNION ALL
SELECT * FROM PendingFiltered
) AS ie
ORDER BY
TimeStampCome DESC
LIMIT 100
OFFSET 1
;Context
StackExchange Database Administrators Q#193519, answer score: 4
Revisions (0)
No revisions yet.