开发者

SQLite table aliases effecting the performance of queries

How does SQLite internally treats the alias?

Does creating a table name alias internally creates a copy of the same table or does it just refers to the same table without creating a copy?

When I create multiple aliases of the same table in my code, performance of the query is severely hit!

In my case, I have one table, call it MainTable with namely 2 columns, name and value. I want to select multiple values in one row as different columns. for example

Name: a,b,c,d,e,f

Value: p,q,r,s,t,u

such that a corresponds to p and so on.

I want to select values for names a,b,c and d in one row => p,q,r,s So I write a query

SELECT t1开发者_如何学C.name, t2.name, t3.name, t4.name  
FROM MainTable t1, MainTable t2, MainTable t3, MainTable t4
WHERE t1.name = 'a' and t2.name = 'b' and t3.name = 'c' and t4.name = 'd';

This way f writing the query kills the performance when size of the table increases as rightly pointed above by Larry.

Is there any efficient way to retrieve this result. I am bad at SQL queries :(


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).


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


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜