mysql select subquery with the same table - mysql

Is it possible to select subquery on same table, i.e.
...(select * from tableA a, select somecolumnA, max(somecolumnB) from tableA group by somecolumnA) b...
... indicates the other queries in the other tables using left joins etc.
will this cause any slowness in mysql?
Actually, I am having error "lost connection to mySQL server during query". I am looking if this part is actually causing the problem.

Related

Is MySQL able to optimize: where `indexed_field` IN (<subquery>)?

Why isn't MySQL able to consistently optimize queries in the format of WHERE <indexed_field> IN (<subquery>)?
I have a query as follows:
SELECT
*
FROM
t1
WHERE
t1.indexed_field IN (select val from ...)
AND (...)
The subquery select val from ... runs very quickly. The problem is MySQL is doing a full table scan to get the required rows from t1 -- even though t1.indexed_field is indexed.
I've gotten around this by changing the query to an inner join:
SELECT
*
FROM
t1
INNER JOIN
(select val from ...) vals ON (vals.val = t1.indexed_field)
WHERE
(...)
Explain shows that this works perfectly -- MySQL is now able use the indexed_field index when joining to the subquery table.
My question is: Why isn't MySQL able to optimize the first query? Intuitively, doing where <indexed_field> IN (<subquery>) seems like quite an easy optimization -- do the subquery, use the index to grab the rows.
No or Yes.
Old versions of MySQL did a very poor job of optimizing IN ( SELECT ... ). It seemed to re-evaluate the subquery repeatedly.
New versions are turning it into EXISTS ( SELECT 1 ... ) or perhaps a LEFT JOIN.
Please provide
Version
SHOW CREATE TABLE
EXPLAIN SELECT ...

Does a union ruin indexing in MySQL 5.6?

A question on how MySQL works under the hood. Say I have two tables, table1, and table2_archive. They are identical in columns and indexed columns.
If I try running queries that involve
(
SELECT * FROM table1
UNION
SELECT * FROM table1
) as allTable1
in the middle of it, with where and join clauses on columns of the newly formed allTable1, are the indexes previously declared on table1/table1_archive now not helpful give they were turned into a new table?
Same qusetion for something like
SELECT IF table1.col1 IS NULL THEN table1_archive.col1 ELSE table1.col1.
I am using MySQL 5.6.

Very slow MySQL subquery

I have two tables that each contain about 500 customer data records. Each record in each of the tables has an email field. Sometimes the same email addresses exist on both tables, sometimes not. I want to retrieve every email address on table1 that doesn't exist on table2. The email field in each table is indexed. I'm doing the select with a sub query that is really slow, 10 to 20 seconds.
select email
from
t1
where
email not in (select email from t2)
There's actually about 30K rows in each table, but I can knock it down to 500 each very quickly with an additional 'where' to filter by category. It's only when I add that subquery that it slows down dramatically. So, I am sure this can be faster, and I know a join should be much faster than the subquery, but can't figure out how to do that. I found a left outer join explanation here on SO, that looked like it should help, but got nowhere with it. Any help is appreciated.
mysql does not optimize a subquery in the WHERE clause (edit: it re-runs the subquery for every row tested)
to convert to a JOIN, try something like
SELECT email FROM t1
LEFT JOIN t2 ON (t1.email = t2.email)
WHERE t2.email IS NULL
this should run very fast, a covering index query.
The query optimizer should walk the email index of t1, check the
email index of t2, and output those emails that are in t1 but not in t2.
Edit: I should add, mysql does optimize a subquery in the JOIN clause: it runs the subquery and puts the results into a "derived table" (temporary table without any indexes), and joins the derived table like any other. The syntax is a bit funny, each derived table must have an alias, ie ... JOIN (SELECT ...) AS derived ON ....
Usually subqueries do more processing than usual query. In your case it first fetches all the emails from t2 and compares it with the email list of t1.
You can try like below, without using a sub query.
SELECT email FROM t1,t2 WHERE t1.email!=t2.email
The best way to improve the performance of SELECT operations is to create indexes on one or more of the columns that are tested in the query. The index entries act like pointers to the table rows, allowing the query to quickly determine which rows match a condition in the WHERE clause, and retrieve the other column values for those rows. All MySQL data types can be indexed.
some tricks for creating mysql tables ..
see this.
I think this should work fine
SELECT email from T1
LEFT JOIN T2
ON T1.email=T2.email
WHERE T2.email!=NULL

Slow query takes up entire HDD space resulting in a "1030 Got error 28 from storage engine"

Fairly new to MySQL.
Slow query takes up the entire HDD space ending up with 1030 error code.
INSERT INTO schema.Table C
SELECT a.`Date`, a.Store, a.SKU,
floor((a.QTY / ((b.CASEQTY * b.CASEPERLAYER) * b.LAYERPERPALLET))) AS Pallets,
floor(((a.QTY / ((b.CASEPERLAYER * b.LAYERPERPALLET) * b.CASEQTY)) /.CASEQTY)) AS Cases,
(a.QTY * b.CASEQTY) AS Pieces
FROM
(schema.table1 AS a
INNER JOIN schema.table2 AS b)
WHERE a.Description = 'BLAH';
Problem:
When I run the above query I get the results I need in 0.01 sec with a limit of 100 rows. However, When I try to insert the query into a prepared table it fails.
The above query will basically run for hours until the HDD is full. Table A contains millions of records and table B only a few thousand. Storage engine is InnoDB. I've run a similar query for 3hrs and have had it succeed. Any help will be greatly appreciated.
That's something special in MySQL. In spite of calling it INNER JOIN, you can do a CROSS JOIN by leaving out the ON clause which is exactly what you are doing. (Another dbms would raise a syntax error.)
So by not specifying the ON clause to match records from table1 and table2 you match every record in table1 with every record in table2. These can be many :-)
Your inner join statement contains no join criteria. This will result in something (bad) called a "cartesian product". So, if table A has a million records and table b contains a thousand, then a cartesian product will match each row in table A to EVERY row in the other table. This should give you (at least) a billion records.
To fix this, you need to define/constrain the relationship between the two tables by using an "ON" clause for your join or it could go in the WHERE clause.

Nested SELECT SQL Queries Workbench

Hi i have this query but its giving me an error of Operand should contain 1 column(s) not sure why?
Select *,
(Select *
FROM InstrumentModel
WHERE InstrumentModel.InstrumentModelID=Instrument.InstrumentModelID)
FROM Instrument
according to your query you wanted to get data from instrument and instrumentModel table and in your case its expecting "from table name " after your select * .when the subselect query runs to get its result its not finding table instrument.InstrumentModelId inorder to fetch result from both the table by matching you can use join .or you can also select perticuler fields by tableName.fieldName and in where condition use your condition.
like :
select Instrument.x,InstrumentModel.y
from instrument,instrumentModel
where instrument.x=instrumentModel.y
You can use a join to select from 2 connected tables
select *
from Instrument i
join InstrumentModel m on m.InstrumentModelID = i.InstrumentModelID
When you use subqueries in the column list, they need to return exactly one value. You can read more in the documentation
as a user commented in the documentation, using subqueries like this can ruin your performance:
when the same subquery is used several times, mysql does not use this fact to optimize the query, so be careful not to run into performance problems.
example:
SELECT
col0,
(SELECT col1 FROM table1 WHERE table1.id = table0.id),
(SELECT col2 FROM table1 WHERE table1.id = table0.id)
FROM
table0
WHERE ...
the join of table0 with table1 is executed once for EACH subquery, leading to very bad performance for this kind of query.
Therefore you should rather join the tables, as described by the other answer.