SQLite table aliases effecting the performance of queries

不打扰是莪最后的温柔 提交于 2019-12-06 11:29:18

Assuming you have table dbo.Customers with a million rows

SELECT * from dbo.Customers A

does not result in a copy of the table being created.

As Larry pointed out, the query as it stands is doing a cartesian product across your table four times which, as you has observed, kills your performance.

The updated ticket states the desire is to have 4 values from different queries in a single row. That's fairly simple, assuming this syntax is valid for sqllite

You can see that the following four queries when run in serial produce the desired value but in 4 rows.

SELECT t1.name
FROM MainTable t1
WHERE t1.name='a';

SELECT t2.name
FROM MainTable t2
WHERE t2.name='b';

SELECT t3.name
FROM MainTable t3
WHERE t3.name='c';

SELECT t4.name
FROM MainTable t4
WHERE t4.name='d';

The trick is to simply run them as sub queries like so there are 5 queries: 1 driver query, 4 sub's doing all the work. This pattern will only work if there is one row returned.

SELECT
(
    SELECT t1.name
    FROM MainTable t1
    WHERE t1.name='a'
) AS t1_name
,
(
    SELECT t2.name
    FROM MainTable t2
    WHERE t2.name='b'
) AS t2_name
,
(
    SELECT t3.name
    FROM MainTable t3
    WHERE t3.name='c'
) AS t3_name
, 
(
    SELECT t4.name
    FROM MainTable t4
    WHERE t4.name='d'
) AS t4_name

If you list the same table more than once in your SQL statement and do not supply conditions on which to JOIN the tables, you are creating a cartesian JOIN in your result set and it will be enormous:

 SELECT * FROM MyTable A, MyTable B;

if MyTable has 1000 records, will create a result set with one million records. Any other selection criteria you include will then have to be evaluated across all one million records.

I'm not sure that's what you're doing (your question is very unclear), but it may be a start on solving your problem.

Updated answer now that the poster has added the query that is being executed.

You're going to have to get a little tricky to get the results you want. You need to use CASE and MAX and, unfortunately, the syntax for CASE is a little verbose:

 SELECT MAX(CASE WHEN name='a' THEN value ELSE NULL END),
        MAX(CASE WHEN name='b' THEN value ELSE NULL END),
        MAX(CASE WHEN name='c' THEN value ELSE NULL END),
        MAX(CASE WHEN name='d' THEN value ELSE NULL END)
  FROM MainTable WHERE name IN ('a','b','c','d');

Please give that a try against your actual database and see what you get (of course, you want to make sure the column name is indexed).

Aliasing a table will result a reference to the original table that exists for the duration of the SQL statement.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!