sqlite join query sample - sql

I have 3 tables that name is productSaleStatus, productSalesVolume, productInfo
The productSaleStatus table structure is
+--------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+-------+
| productCode | int(11) | YES | | NULL | |
| sales | int(11) | YES | | NULL | |
| year | int(11) | YES | | NULL | |
| month | int(11) | YES | | NULL | |
| day | int(11) | YES | | NULL | |
| aFewWeeks | int(11) | YES | | NULL | |
| dayOfTheWeek | int(11) | YES | | NULL | |
+--------------+---------+------+-----+---------+-------+
The productSalesVolume table structure is
+------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+-------+
| productCode | int(11) | YES | | NULL | |
| optimumInventory | int(11) | YES | | NULL | |
| productDate | date | YES | | NULL | |
+------------------+---------+------+-----+---------+-------+
The productInfo table structure is
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| productCode | int(11) | YES | | NULL | |
| productName | varchar(10) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
The example data of productSaleStatus is
+-------------+-------+------+-------+------+-----------+--------------+
| productCode | sales | year | month | day | aFewWeeks | dayOfTheWeek |
+-------------+-------+------+-------+------+-----------+--------------+
| 1 | 100 | 2016 | 9 | 30 | 2 | 1 |
| 2 | 200 | 2016 | 10 | 30 | 2 | 1 |
| 1 | 150 | 2017 | 1 | 1 | 2 | 1 |
| 2 | 125 | 2017 | 1 | 2 | 2 | 1 |
+-------------+-------+------+-------+------+-----------+--------------+
The example data of productSalesVolume is
+-------------+------------------+-------------+
| productCode | optimumInventory | productDate |
+-------------+------------------+-------------+
| 1 | 500 | 2016-10-10 |
| 2 | 1000 | 2016-10-08 |
| 1 | 1500 | 2016-10-20 |
| 2 | 2000 | 2017-01-01 |
+-------------+------------------+-------------+
The example data of productInfo is
+-------------+-------------+
| productCode | productName |
+-------------+-------------+
| 1 | test |
| 2 | hello |
+-------------+-------------+
So what i want expect result is
1, test, 150, 2017, 1, 1, 1500, 2016-10-20
2, hello, 125, 2017, 1, 2, 2000, 2017-01-01
Can anyone write sample query to me?

Based on the sample data you provided, this should produce the results you say you want. Though I think you may need to add in a group by and sum sales with a full data set
SELECT pi.ProductName, pss.sales, pss.month, pss.day, psv.optimumInventory, psv.productDate
FROM productSaleStatus pss
INNER JOIN productInfo pi
ON pss.productCode = pi.productCode
INNER JOIN productSalesVolume psv
ON pss.productCode = psv.productCode
WHERE pss.year = '2017'

Related

SQL count results on left join

I'm trying to get the total count of a table from a left join where there's a multiple of the same id. Here's my example below -
Table 1:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| project_id | int(11) | NO | | NULL | |
| token | varchar(32) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| status | char(1) | NO | | 0 | |
| permissions | varchar(255) | YES | | NULL | |
| created | datetime | NO | | NULL | |
| modified | datetime | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
Table 2:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| account_id | int(11) | NO | | NULL | |
| created | datetime | NO | | NULL | |
| modified | datetime | NO | | NULL | |
| active | tinyint(1) | YES | | 1 | |
+------------+-------------+------+-----+---------+----------------+
I have this statement so far -
SELECT account_id, (SELECT COUNT(invitations.id)
FROM invitations WHERE invitations.project_id = projects.id) AS inv_count
FROM projects order by account_id;
And here's a sample of the results:
+------------+-----------+
| account_id | inv_count |
+------------+-----------+
| 1 | 0 |
| 2 | 2 |
| 2 | 0 |
| 3 | 4 |
| 3 | 0 |
| 3 | 4 |
| 3 | 0 |
| 4 | 6 |
| 4 | 3 |
| 4 | 3 |
| 4 | 5 |
| 4 | 3 |
| 4 | 9 |
| 5 | 6 |
| 5 | 0 |
| 5 | 4 |
| 5 | 2 |
| 5 | 2 |
How do I get account_id to show once and the sum of inv_count to show as 1 line? So I should see -
+------------+-----------+
| account_id | inv_count |
+------------+-----------+
| 1 | 0 |
| 2 | 2 |
| 3 | 8 |
You only need to put your query in a derived table (and name it, say tmp) and then group by the account_id:
SELECT account_id,
SUM(inv_count) AS inv_count
FROM
( SELECT account_id,
(SELECT COUNT(invitations.id)
FROM invitations
WHERE invitations.project_id = projects.id
) AS inv_count
FROM projects
) AS tmp
GROUP BY account_id
ORDER BY account_id ;
To simplify it farther, you can convert the inline subquery to a LEFT join. This way, no derived table is needed. I've also added aliases and removed the ORDER BY. MySQL does an implicit ORDER BY when you have GROUP BY so it's not needed here (unless you want to order by some other expression, different from the one you group by):
SELECT
p.account_id,
COUNT(i.id) AS inv_count
FROM
projects AS p
LEFT JOIN
invitations AS i
ON i.project_id = p.id
GROUP BY
p.account_id ;

Why is this SQL generating a temporary table and running so slow?

I have the following SQL generated from my Rails app, it is trying to get a list of all auto models that have live adverts in a marketplace app & from mysql:
SELECT `models`.* FROM `models`
INNER JOIN `autos` ON autos.model_id = models.id
INNER JOIN `ads` ON `ads`.id = `autos`.ad_id
WHERE (ads.ad_status_id = 4 AND pub_start_date < NOW() AND pub_end_date > NOW() AND models.manufacturer_id = 50 )
GROUP BY models.id ORDER BY models.name;
When I run an explain, this is what I get:
Id 1 1 1
Select Type SIMPLE SIMPLE SIMPLE
Table models autos ads
Type ref ref eq_ref
Possible Keys PRIMARY,manufacturer_id model_id,ad_id PRIMARY,quick_search,ad_status_id
Key manufacturer_id model_id PRIMARY
Key Length 5 4 4
Ref const concept_development.models.id concept_development.autos.ad_id
Rows 70 205 1
Extra Using where; Using temporary; Using filesort Using where Using where
I cannot understand why the query is generating a temporary table / using file-sort - all of the referenced keys are indexes. Been trying to figure this out for a few days now and getting nowhere.
Any help is very much appreciated!
EXPLAIN models:
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | YES | | NULL | |
| manufacturer_id | int(11) | YES | MUL | NULL | |
| vehicle_category_id | int(11) | NO | MUL | 1 | |
| synonym_names | longtext | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
SHOW INDEXES FROM models:
+--------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| models | 0 | PRIMARY | 1 | id | A | 2261 | NULL | NULL | | BTREE | |
| models | 1 | manufacturer_id | 1 | manufacturer_id | A | 205 | NULL | NULL | YES | BTREE | |
| models | 1 | vehicle_category_id | 1 | vehicle_category_id | A | 7 | NULL | NULL | | BTREE | |
+--------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
MODEL TABLE STATUS:
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+---------+
| models | MyISAM | 10 | Dynamic | 2261 | 26 | 61000 | 281474976710655 | 84992 | 0 | 2751 | 2010-09-28 18:42:45 | 2010-09-28 18:42:45 | 2010-09-28 18:44:00 | latin1_swedish_ci | NULL | | |
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+---------+
EXPLAIN ADS
+------------------+--------------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------------------+------+-----+---------------------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| fp_urn | int(10) | NO | MUL | 0 | |
| user_id | int(10) | NO | MUL | 0 | |
| ad_status_id | int(3) unsigned | NO | MUL | 1 | |
| style_id | int(10) | NO | | 3 | |
| search_tags | varchar(255) | YES | | NULL | |
| title | varchar(255) | NO | | | |
| description | text | YES | | NULL | |
| currency | enum('EUR','GBP') | NO | | EUR | |
| price | decimal(8,2) | NO | MUL | 0.00 | |
| proposal_type | enum('Offered','Wanted') | NO | | Offered | |
| category_id | int(10) | YES | | 0 | |
| contact | varchar(50) | NO | MUL | | |
| area_id | int(10) | NO | | 0 | |
| origin_id | int(10) | NO | | 0 | |
| reject_reason_id | int(3) | NO | | 0 | |
| date_created | timestamp | NO | | 0000-00-00 00:00:00 | |
| last_modified | timestamp | NO | | CURRENT_TIMESTAMP | |
| pub_start_date | datetime | YES | | 0000-00-00 00:00:00 | |
| pub_end_date | datetime | YES | | 0000-00-00 00:00:00 | |
| bumped_up_date | datetime | YES | | 0000-00-00 00:00:00 | |
| state | smallint(6) | YES | | NULL | |
| eproofed | tinyint(1) | NO | | 0 | |
| is_featured | int(1) | NO | | 0 | |
| num_featured_imp | int(10) | YES | | 0 | |
| num_direct_imp | int(10) | YES | | 0 | |
| is_top_listed | int(1) | NO | | 0 | |
| delta | tinyint(1) | NO | | 0 | |
| ext_ref_id | varchar(50) | YES | | NULL | |
| email_seller | tinyint(1) | YES | | 1 | |
| sort_by | int(10) | YES | | 8 | |
| permalink | varchar(500) | YES | | NULL | |
| external_url | varchar(255) | YES | | NULL | |
+------------------+--------------------------+------+-----+---------------------+----------------+
SHOW TABLE STATUS FROM concept_development WHERE NAME LIKE 'ads';
+------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
| ads | InnoDB | 10 | Compact | 656350 | 232 | 152748032 | 0 | 87736320 | 340787200 | 1148382 | 2010-09-29 09:55:46 | NULL | NULL | utf8_general_ci | NULL | checksum=1 delay_key_write=1 row_format=DYNAMIC | |
+------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
SHOW INDEXES FROM ADS
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
| ads | 0 | PRIMARY | 1 | id | A | 521391 | NULL | NULL | | BTREE | |
| ads | 1 | NewIndex1 | 1 | ad_status_id | A | 15 | NULL | NULL | | BTREE | |
| ads | 1 | NewIndex1 | 2 | pub_end_date | A | 260695 | NULL | NULL | YES | BTREE | |
| ads | 1 | NewIndex1 | 3 | category_id | A | 521391 | NULL | NULL | YES | BTREE | |
| ads | 1 | NewIndex1 | 4 | style_id | A | 521391 | NULL | NULL | | BTREE | |
| ads | 1 | NewIndex2 | 1 | user_id | A | 130347 | NULL | NULL | | BTREE | |
| ads | 1 | NewIndex3 | 1 | price | A | 7667 | NULL | NULL | | BTREE | |
| ads | 1 | contact | 1 | contact | A | 260695 | NULL | NULL | | BTREE | |
| ads | 1 | fp_urn | 1 | fp_urn | A | 521391 | NULL | NULL | | BTREE | |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
EXPLAIN autos
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| ad_id | int(10) | YES | MUL | NULL | |
| style_id | int(10) | YES | MUL | NULL | |
| manufacturer_id | int(10) | NO | MUL | NULL | |
| model_id | int(10) | NO | MUL | NULL | |
| registration | varchar(10) | YES | | NULL | |
| year | int(4) | YES | | NULL | |
| fuel_type | enum('Petrol','Diesel') | NO | | Petrol | |
| colour | varchar(75) | YES | | NULL | |
| mileage | varchar(25) | NO | | Not Entered | |
| mileage_units | enum('mls','kms') | NO | | mls | |
| num_doors | varchar(25) | NO | | Not Entered | |
| num_owners | int(2) | YES | | NULL | |
| engine_size | varchar(10) | YES | | NULL | |
| transmission_type | enum('Manual','Automatic') | NO | | Manual | |
| body_type | enum('Saloon','Hatchback') | NO | | Saloon | |
| condition | varchar(75) | NO | | NA | |
| extra_features | text | YES | | NULL | |
| tax_expiry | varchar(7) | YES | | NULL | |
| nct_expiry | varchar(7) | YES | | NULL | |
| variation | text | YES | | NULL | |
| tax_class | enum('Agricultural','Bus') | NO | | Private | |
| co2 | int(9) | YES | | NULL | |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------+----------------+
SHOW TABLE STATUS FROM concept_development WHERE NAME LIKE 'autos'
+-------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
| autos | InnoDB | 10 | Compact | 196168 | 136 | 26804224 | 0 | 26279936 | 340787200 | 485405 | 2010-09-17 22:09:45 | NULL | NULL | utf8_general_ci | NULL | checksum=1 delay_key_write=1 row_format=DYNAMIC | |
+-------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+-------------------------------------------------+---------+
show indexes from autos;
+-------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+
| autos | 0 | PRIMARY | 1 | id | A | 294937 | NULL | NULL | | BTREE | |
| autos | 1 | ad_id | 1 | ad_id | A | 294937 | NULL | NULL | YES | BTREE | |
| autos | 1 | style_id | 1 | style_id | A | 10 | NULL | NULL | YES | BTREE | |
| autos | 1 | manufacturer_id | 1 | manufacturer_id | A | 194 | NULL | NULL | | BTREE | |
| autos | 1 | model_id | 1 | model_id | A | 830 | NULL | NULL | | BTREE | |
+-------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+
From the MySQL documentation:
Temporary tables can be created under conditions such as these:
* If there is an ORDER BY clause and a different GROUP BY clause, or if the ORDER BY or GROUP BY contains columns from tables other than the first table in the join queue, a temporary table is created.
http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html
Change all the text columns to varchar. If you need to maintain them as "text", you'll need to snowflake the schema and exclude the description tables from this query.
If any of the columns in any of the tables are text or blob, MySQL automatically creates an on-disk temporary table, rather than an in-memory temporary table. The temporary table itself isn't killing you, it's the fact that it's writing it to the disk.
http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html
Some conditions prevent the use of an in-memory temporary table, in which case the server uses an on-disk table instead:
Presence of a BLOB or TEXT column in the table
You have a index on pub_end_date, but not on pub_start_date and your WHERE clause references both.
It looks like it is not using the pub_end_date index, but this could be because it needs to check pub_start_date as well.
This isn't explaining why but how about you rewrite your query to not use a group by? I think you're just joining on those tables to ensure there exists an ad of interest. So how about:
SELECT `models`.*
FROM `models`
WHERE models.manufacturer_id = 50
AND EXISTS ( SELECT * FROM `autos`
INNER JOIN `ads` ON `ads`.id = `autos`.ad_id
WHERE autos.model_id = models.id
AND ads.ad_status_id = 4
AND ads.pub_start_date < NOW()
AND ads.pub_end_date > NOW()
)
ORDER BY models.name;
The performance issues might be related to the group by, in which case this would improve performance.
Maybe it'd look a bit nicer with and NOW() between ads.pub_start_date and ads.pub_end_date, if you're allowed to do that in mysql (and if it works how you want with the edge cases).

MySQL ignores my index

I'm running the following query in MYSQL
select distinct straight_join
cu.entryid entryid,
t0.tokpos starting_position,
t3.tokpos ending_position,
t0.idxsent idxsent,
'TOKENS_44_340' tablename
from
TOKENS_44_340 t0,
constraints_appraisal cu,
TOKENS_44_340 t1,
TOKENS_44_340 t2,
TOKENS_44_340 t3
where
t0.token_surface = cu.token_0
and (cu.pos_0 is null OR t0.penntag like concat(cu.pos_0,'%'))
and t1.token_surface = cu.token_1
and (cu.pos_1 is null OR t1.penntag like concat(cu.pos_1,'%'))
and t2.token_surface = cu.token_2
and (cu.pos_2 is null OR t2.penntag like concat(cu.pos_2,'%'))
and t3.token_surface = cu.token_3
and (cu.pos_3 is null OR t3.penntag like concat(cu.pos_3,'%'))
and t0.tokpos = t1.tokpos - 1
and t1.tokpos = t2.tokpos - 1
and t2.tokpos = t3.tokpos - 1
and cu.token_4 is null
and cu.token_5 is null
and cu.token_6 is null
and cu.token_7 is null
and cu.token_8 is null
and cu.token_9 is null;
MySQL gives me the following query plan for this query:
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
| 1 | SIMPLE | t0 | ALL | PRIMARY,TOKENS_44_340_index_44,tokpos | NULL | NULL | NULL | 49 | Using temporary |
| 1 | SIMPLE | cu | ALL | NULL | NULL | NULL | NULL | 7907 | Using where |
| 1 | SIMPLE | t1 | ref | PRIMARY,TOKENS_44_340_index_44,tokpos | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
| 1 | SIMPLE | t2 | ref | PRIMARY,TOKENS_44_340_index_44,tokpos | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
| 1 | SIMPLE | t3 | ref | TOKENS_44_340_index_44 | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
5 rows in set (0.00 sec)
As you can see, MySQL doesn't even so much as acknowledge the existance of my index token_0 on constraints_appraisal(token_0). Any idea why it's ignoring my index, and what I can do about it? I'm running mysql 5.0.51a-24+lenny4 for Debian stable.
P.S. I know I could make this query run faster by removing the straight_join constraint and let it use the token_surface index on t0, but it still wouldn't be as fast as it could be using the token_0 index on constraints_appraisal. I added the straight_join so that I could make my specific issue appear more clearly, and I plan remove it when I have the index working properly.
mysql> describe TOKENS_44_340;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| tokPos | int(11) | NO | PRI | NULL | |
| linePos | int(11) | YES | | NULL | |
| EOLs | int(11) | YES | | NULL | |
| idxsent | int(11) | YES | | NULL | |
| possent | int(11) | YES | | NULL | |
| brilltag | int(11) | YES | | NULL | |
| token_surface | varchar(132) | YES | MUL | NULL | |
| wordLen | int(11) | YES | | NULL | |
| capitalized | int(11) | YES | | NULL | |
| wordType | int(11) | YES | | NULL | |
| numDigit | int(11) | YES | | NULL | |
| numPunc | int(11) | YES | | NULL | |
| numAlpha | int(11) | YES | | NULL | |
| maxRep | int(11) | YES | | NULL | |
| pre1 | varchar(132) | YES | | NULL | |
| pre2 | varchar(132) | YES | | NULL | |
| pre3 | varchar(132) | YES | | NULL | |
| pre4 | varchar(132) | YES | | NULL | |
| suf1 | varchar(132) | YES | | NULL | |
| suf2 | varchar(132) | YES | | NULL | |
| suf3 | varchar(132) | YES | | NULL | |
| suf4 | varchar(132) | YES | | NULL | |
| dep_gov | int(11) | YES | MUL | NULL | |
| dep_rel | varchar(20) | YES | MUL | NULL | |
| penntag | varchar(30) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
25 rows in set (0.04 sec)
mysql> describe constraints_appraisal;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| entryid | int(11) | NO | PRI | 0 | |
| context | varchar(50) | YES | | NULL | |
| syntax | int(11) | YES | | NULL | |
| token_0 | varchar(50) | YES | MUL | NULL | |
| pos_0 | varchar(50) | YES | | NULL | |
| porter_0 | varchar(50) | YES | MUL | NULL | |
| token_1 | varchar(50) | YES | | NULL | |
| pos_1 | varchar(50) | YES | | NULL | |
| porter_1 | varchar(50) | YES | | NULL | |
| token_2 | varchar(50) | YES | | NULL | |
| pos_2 | varchar(50) | YES | | NULL | |
| porter_2 | varchar(50) | YES | | NULL | |
| token_3 | varchar(50) | YES | | NULL | |
| pos_3 | varchar(50) | YES | | NULL | |
| porter_3 | varchar(50) | YES | | NULL | |
| token_4 | varchar(50) | YES | | NULL | |
| pos_4 | varchar(50) | YES | | NULL | |
| porter_4 | varchar(50) | YES | | NULL | |
| token_5 | varchar(50) | YES | | NULL | |
| pos_5 | varchar(50) | YES | | NULL | |
| porter_5 | varchar(50) | YES | | NULL | |
| token_6 | varchar(50) | YES | | NULL | |
| pos_6 | varchar(50) | YES | | NULL | |
| porter_6 | varchar(50) | YES | | NULL | |
| token_7 | varchar(50) | YES | | NULL | |
| pos_7 | varchar(50) | YES | | NULL | |
| porter_7 | varchar(50) | YES | | NULL | |
| token_8 | varchar(50) | YES | | NULL | |
| pos_8 | varchar(50) | YES | | NULL | |
| porter_8 | varchar(50) | YES | | NULL | |
| token_9 | varchar(50) | YES | | NULL | |
| pos_9 | varchar(50) | YES | | NULL | |
| porter_9 | varchar(50) | YES | | NULL | |
| token_surface | varchar(200) | YES | | NULL | |
| fileid | varchar(100) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
35 rows in set (0.06 sec)
mysql> show index from constraints_appraisal;
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| constraints_appraisal | 0 | PRIMARY | 1 | entryid | A | 7907 | NULL | NULL | | BTREE | |
| constraints_appraisal | 1 | token_0 | 1 | token_0 | A | NULL | NULL | NULL | YES | BTREE | |
| constraints_appraisal | 1 | porter_0 | 1 | porter_0 | A | NULL | NULL | NULL | YES | BTREE | |
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.05 sec)
It appears that the problem is that the two tables are in different character sets.
TOKENS_44_340 is in utf8
constraints_appraisal is in latin1

mysql three joins

I have a problem with mysql
I have 3 tables:
Deposit
+-------------------+-------------+------+-----+
| Field | Type | Null | Key |
+-------------------+-------------+------+-----+
| id | bigint(20) | NO | PRI |
| status | int(2) | NO | |
| depositDate | datetime | NO | MUL |
| reversePayment_id | bigint(20) | YES | UNI |
| claim_id | int(2) | NO | UNI |
| payment_id | bigint(20) | YES | UNI |
+-------------------+-------------+------+-----+
Payment
+--------------------------+---------------+------+-----+
| Field | Type | Null | Key |
+--------------------------+---------------+------+-----+
| id | int(10) | NO | PRI |
| paymentDate | timestamp | NO | MUL |
| pin | int(10) | NO | MUL |
| balanceChange | decimal(15,2) | YES | |
Claim
+------------------------+--------------+------+-----+
| Field | Type | Null | Key |
+------------------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| fullName | varchar(100) | NO | |
| depositSum | blob | NO | |
| ip | varchar(39) | NO | |
| status | int(2) | NO | |
+------------------------+--------------+------+-----+
I try to select deposits (with claims) payment or reversePayment were between two dates, I perform this query with 3 joins:
EXPLAIN SELECT this_.id AS id60_3_, ..., fcpayment2_.id AS id59_0_, ..., reversepay3_.id AS id59_1_, ..., cl1_.id AS id61_2_, ...
FROM Deposit this_
INNER JOIN Payment fcpayment2_ ON this_.payment_id = fcpayment2_.id
LEFT OUTER JOIN Payment reversepay3_ ON this_.reversePayment_id = reversepay3_.id
INNER JOIN Claim cl1_ ON this_.claim_id = cl1_.id
WHERE (
(
fcpayment2_.paymentDate >= '2010-08-04 21:00:00'
AND fcpayment2_.paymentDate <= '2010-08-05 08:01:00'
)
OR (
reversepay3_.paymentDate >= '2010-08-04 21:00:00'
AND reversepay3_.paymentDate <= '2010-08-05 08:01:00'
)
)
ORDER BY this_.depositDate DESC
the result is
+----+-------------+--------------+--------+--------------------------------------------------------------------+----------+---------+-----------------------------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+--------------------------------------------------------------------+----------+---------+-----------------------------------------+--------+---------------------------------+
| 1 | SIMPLE | cl1_ | ALL | PRIMARY | NULL | NULL | NULL | 426588 | Using temporary; Using filesort |
| 1 | SIMPLE | this_ | eq_ref | claim_id,payment_id,FKDB5A0548511B6CDD,FKDB5A054867BA4108 | claim_id | 4 | portal.cl1_.id | 1 | |
| 1 | SIMPLE | fcpayment2_ | eq_ref | PRIMARY,paymentDate,date | PRIMARY | 4 | portal.this_.payment_id | 1 | Using where |
| 1 | SIMPLE | reversepay3_ | eq_ref | PRIMARY | PRIMARY | 4 | portal.this_.reversePayment_id | 1 | Using where |
+----+-------------+--------------+--------+--------------------------------------------------------------------+----------+---------+-----------------------------------------+--------+---------------------------------+
Why the first table in result is cl1_ and why mysql doesn't use key?
Because you used the keyword 'Explain', and because cl1_ is the alias you gave the table in your query.
I don't understand your question about the key.

Why is my query so slow? Trying to find the null fields on a left join in mysql

EDIT: Updated with suggestions from Bill Karwin below. Still very slow.
I'm trying to write a query that will find all items on an order that are entered to a warehouse that doesn't have a record for that item in that warehouse. As an example, if item XYZ is entered for warehouse A, but warehouse A doesn't actually carry item XYZ, I want the order item to show up in my report.
I'm able to run the query just fine, but it seems to take forever (50 seconds). It seems to be hanging mainly on the "is null" condition I have in the where clause. If I remove the condition with the "is null" and run it, it executes in about 4.8s. Here's my query:
SELECT
saw_order.Wo,
saw_orderitem.Item,
saw_orderitem.Stock,
saw_order.`Status`,
saw_order.`Date`,
saw_orderitem.Warehouse,
saw_stockbalance.Balno,
saw_stockbalance.Stock
FROM
saw_order
Inner Join saw_orderitem ON saw_order.Wo = saw_orderitem.Wo
Inner Join saw_stock ON saw_orderitem.Stock = saw_stock.Stock
Left Join saw_stockbalance ON saw_orderitem.Stock = saw_stockbalance.Stock
AND saw_orderitem.Warehouse = saw_stockbalance.Warehouse
WHERE
saw_order.`Status` Between 3 and 81 and
saw_stockbalance.Stock Is Null
When I explain the query above, I see:
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
| 1 | SIMPLE | saw_stock | index | PRIMARY | PRIMARY | 17 | NULL | 32793 | Using index |
| 1 | SIMPLE | saw_orderitem | ref | PRIMARY,Stock,StockWarehouse | Stock | 17 | saws.saw_stock.Stock | 68 | |
| 1 | SIMPLE | saw_order | eq_ref | PRIMARY,Status | PRIMARY | 4 | saws.saw_orderitem.Wo | 1 | Using where |
| 1 | SIMPLE | saw_stockbalance | ref | Stock,Warehouse | Stock | 20 | saws.saw_orderitem.Stock,saws.saw_orderitem.Warehouse | 1 | Using where; Not exists |
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
I'm pretty sure I have indexes for all of the fields of the respective tables in my joins, but can't figure out how to rewrite the query to make it go faster.
EDIT: Here are the indexes I have set up on my tables:
mysql> show index from saw_order;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_order | 0 | PRIMARY | 1 | Wo | A | 553425 | NULL | NULL | | BTREE | |
| saw_order | 1 | Customer | 1 | Customer | A | 14957 | NULL | NULL | | BTREE | |
| saw_order | 1 | Other | 1 | Other | A | 218 | NULL | NULL | | BTREE | |
| saw_order | 1 | Site | 1 | Site | A | 8 | NULL | NULL | | BTREE | |
| saw_order | 1 | Date | 1 | Date | A | 1594 | NULL | NULL | | BTREE | |
| saw_order | 1 | Status | 1 | Status | A | 15 | NULL | NULL | | BTREE | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
6 rows in set
mysql> show index from saw_orderitem;
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_orderitem | 0 | PRIMARY | 1 | Wo | A | NULL | NULL | NULL | | BTREE | |
| saw_orderitem | 0 | PRIMARY | 2 | Item | A | 1842359 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Stock | 1 | Stock | A | 27093 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Product | 1 | Product | A | 803 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | GGroup | 1 | GGroup | A | 114 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | ShipVia | 1 | ShipVia | A | 218 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Warehouse | 1 | Warehouse | A | 9 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | StockWarehouse | 1 | Stock | A | 27093 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | StockWarehouse | 2 | Warehouse | A | 49793 | NULL | NULL | | BTREE | |
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
9 rows in set
mysql> show index from saw_stock;
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_stock | 0 | PRIMARY | 1 | Stock | A | 32793 | NULL | NULL | | BTREE | |
| saw_stock | 1 | Class | 1 | Class | A | 655 | NULL | NULL | YES | BTREE | |
| saw_stock | 1 | DateFirstReceived | 1 | DateFirstReceived | A | 2732 | NULL | NULL | | BTREE | |
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set
mysql> show index from saw_stockbalance;
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_stockbalance | 0 | PRIMARY | 1 | Balno | A | 146315 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Stock | 1 | Stock | A | 36578 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Stock | 2 | Warehouse | A | 146315 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Warehouse | 1 | Warehouse | A | 11 | NULL | NULL | | BTREE | |
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set
Any ideas?
I'd try to make it use a covering index. That is, instead of testing if Balno is null, test if one of the columns in your left outer join conditions is null. E.g. Stock or Warehouse.
You should also define an index over the two columns (Stock, Warehouse) in both tables saw_orderitem and saw_stockbalance.
Try:
SELECT t.wo,
soi.item,
soi.stock,
t.Status,
t.Date,
soi.warehouse,
NULL 'balno', --ssb.Balno,
NULL 'stock', --ssb.Stock
FROM SAW_ORDER t
JOIN SAW_ORDERITEM soi ON soi.wo = t.wo
JOIN SAW_STOCK ss ON ss.stock = soi.stock
WHERE t.status BETWEEN 3 AND 81
AND NOT EXISTS (SELECT NULL
FROM SAW_STOCKBALANCE ssb
WHERE ssb.stock != soi.stock
AND ssb.warehouse = soi.warehouse)
The problem with the query is that you are checking for nulls on a LEFT JOIN...