how to optimize the below MYSQL query - mysql

the below query it scans more rows while the table has an index on it but not using that index for that column.
Query;
SELECT
*
FROM
st_aepsrequest_log
WHERE
`snd_transno` IN (
SELECT
pwcashout_transno
FROM
st_aeps_transaction_master a
WHERE
a.`entry_date` >= '2022-09:29 13:00:00'
AND a.entry_date <= '2022-09-29 13:30:00'
)
row scans;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: st_aepsrequest_log
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 7355201
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: a
partitions: NULL
type: eq_ref
possible_keys: snd_unique,pwaeps_transno,entry_date
key: snd_unique
key_len: 92
ref: func
rows: 1
filtered: 5.00
Extra: Using index condition; Using where
table structure;
*************************** 1. row ***************************
Table: st_aepsrequest_log
Create Table: CREATE TABLE `st_aepsrequest_log` (
`serno` int(11) NOT NULL AUTO_INCREMENT,
`db_serno` char(2) NOT NULL DEFAULT '',
`brand` char(2) NOT NULL DEFAULT '',
`counter_code` char(20) NOT NULL DEFAULT '',
`transno` char(30) NOT NULL DEFAULT '',
`snd_transno` char(30) NOT NULL DEFAULT '',
`latlog` char(100) NOT NULL DEFAULT '',
`trans_mode` char(20) NOT NULL DEFAULT '',
`amount` double NOT NULL DEFAULT '0',
`intime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`outtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_agent` text NOT NULL,
`remote_ip` text NOT NULL,
`request` text NOT NULL,
`response` text NOT NULL,
`url` text NOT NULL,
PRIMARY KEY (`serno`),
KEY `sndtransno` (`snd_transno`)
) ENGINE=InnoDB AUTO_INCREMENT=16912804 DEFAULT CHARSET=latin1
*************************** 1. row ***************************
Table: st_aeps_transaction_master
Create Table: CREATE TABLE `st_aeps_transaction_master` (
`serno` bigint(20) NOT NULL AUTO_INCREMENT,
`entry_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`mode_id` varchar(20) NOT NULL DEFAULT '',
`db_serno` char(2) NOT NULL DEFAULT '',
`merchant_id` int(10) unsigned NOT NULL DEFAULT '0',
`service_group_id` int(10) unsigned NOT NULL,
`merchant_channel` enum('RETAIL','B2C') DEFAULT NULL,
`merchant_users_id` varchar(20) NOT NULL,
`provider_user_id` varchar(100) NOT NULL DEFAULT '',
`merchant_transno` varchar(50) DEFAULT '',
`pwcashout_transno` varchar(30) NOT NULL,
`rrn` varchar(100) DEFAULT NULL,
`pw_stan` varchar(50) NOT NULL DEFAULT '',
`provider_id` int(10) unsigned NOT NULL DEFAULT '0',
`service_id` int(10) unsigned NOT NULL,
`bank_id` int(11) NOT NULL DEFAULT '0',
`amount` double DEFAULT '0',
`total_comm` double NOT NULL DEFAULT '0',
`provider_comm` double NOT NULL DEFAULT '0',
`gst` enum('INCLUSIVE','EXCLUSIVE') NOT NULL DEFAULT 'INCLUSIVE',
`gst_value` double NOT NULL DEFAULT '0',
`aadhar_no` char(12) NOT NULL DEFAULT '',
`aeps_identifier` char(50) NOT NULL DEFAULT '',
`provider_rate_mode` enum('PERCENT','AMOUNT','CUSTOM') DEFAULT 'PERCENT',
`device_info` varchar(200) NOT NULL DEFAULT '',
`device` varchar(20) DEFAULT NULL,
`device_serno` varchar(20) NOT NULL DEFAULT '',
`client_ip` varchar(20) NOT NULL DEFAULT '',
`refund_date` datetime DEFAULT '0000-00-00 00:00:00',
`requery_date` datetime DEFAULT '0000-00-00 00:00:00',
`provider_response_message` text,
`provider_response_code` varchar(20) NOT NULL DEFAULT '',
`response` text NOT NULL,
`trans_settle_date` date NOT NULL DEFAULT '0000-00-00',
`trans_settle_datetime` datetime DEFAULT '0000-00-00 00:00:00',
`trans_settle_status` char(1) NOT NULL DEFAULT 'N',
`status` enum('INITIATED','SUCCESS','FAILED') NOT NULL,
PRIMARY KEY (`serno`),
UNIQUE KEY `snd_unique` (`pwcashout_transno`),
KEY `pwaeps_transno` (`pwcashout_transno`),
KEY `merchant_transno` (`merchant_transno`),
KEY `entry_date` (`entry_date`),
KEY `provider_id` (`provider_id`),
KEY `trans_settle_datetime` (`trans_settle_datetime`),
KEY `idx_ent_merc` (`merchant_users_id`,`entry_date`)
) ENGINE=InnoDB AUTO_INCREMENT=87032220 DEFAULT CHARSET=utf8
is there any way to optimize the above query?
i have added the format of the databases
dfsdfdsfdsfdsfdsfdsfdsfdsfsdfsdfdsfdsfdsf
fdshfjsdhjkfhkjdshkfhsjkdfhkdfjhdsjhfgdhjgfjhdjfhgdshjfgjdsf

Character sets and collations are baked into indexes on columns with data types like the CHAR(30) you use for st_aepsrequest_log.snd_transno and st_aeps_transaction_master.pwcashout_transno. So, like #BillKarwin mentioned, if the character sets and collations vary it defeats the use of indexes.
Now, it looks like your subquery SELECT pwcashout_transno ... produces a modest number of rows in its result set. And, the character set for st_aepsrequest_log.snd_transno is latin1. So if you convert the output of the subquery to latin1, it should be possible for your IN() clause to use the index on that column. SELECT CONVERT(pwcashout_transno USING latin1) should do the trick. Try this version of your query:
SELECT
*
FROM
st_aepsrequest_log
WHERE
`snd_transno` IN (
SELECT
CONVERT(pwcashout_transno USING latin1)
FROM
st_aeps_transaction_master a
WHERE
a.`entry_date` >= '2022-09:29 13:00:00'
AND a.entry_date <= '2022-09-29 13:30:00'
)
But this is a bit of a hack. It's always better when doing your table design to make the character sets and collations of CHAR() and VARCHAR() columns match. This is especially true if you JOIN on them or use them on IN() or = clauses.
Of course, redefining the tables may not be possible for your application.

If the query from OJones does not work, then avoid IN ( SELECT ... ) by doing this:
SELECT log.*
FROM
( SELECT CONVERT(a.pwcashout_transno USING latin1) AS pt
FROM st_aeps_transaction_master a
WHERE a.entry_date >= '2022-09:29 13:00:00'
AND a.entry_date < '2022-09-29 13:00:00'
+ INTERVAL 30 MINUTE
) AS x
JOIN st_aepsrequest_log AS log ON log.snd_transno = x.pt
Then, this index may help: INDEX(entry_date, pwcashout_transno)
Note: If there could be multiple rows with the same pwcashout_transno, then the inner (derived) query may need DISTINCT.

Related

how to rewrite a join query with CTE?

here I have tried to rewrite the query with cte cuz of good readability but when I try to rewrite the data is mismatched how to solve the problem for this?
Query;
select count(1) as rage_tap
from ue_summary.summary_funnel_1066 s
join user_tasks_metadata utm on utm.asi = s.asi
join user_tasks ut on ut.id = utm.user_task_id
where s.seq_no = 1
and s.created_at between '2022-09-27 00:00:00' and '2022-10-27 00:00:00'
and ut.is_ragetap = 1
Explain plan ;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ut
partitions: NULL
type: ref
possible_keys: PRIMARY,idx_ir
key: idx_ir
key_len: 1
ref: const
rows: 8413412
filtered: 100.00
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: utm
partitions: NULL
type: ref
possible_keys: id_asi,asi
key: id_asi
key_len: 8
ref: ue_stage.ut.id
rows: 1
filtered: 100.00
Extra: Using index
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: s
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,unique_asi_seq_no,seq_no_date,created_at,idx_combo,idx_seq_created_asi
key: unique_asi_seq_no
key_len: 12
ref: ue_stage.utm.asi,const
rows: 1
filtered: 50.00
Extra: Using where; Using index
Table structure;
Create Table: CREATE TABLE `summary_funnel_1066` (
`funnel_id` int DEFAULT NULL,
`app_id` int DEFAULT NULL,
`platform` int DEFAULT NULL,
`app_version_id` int NOT NULL,
`seq_no` int NOT NULL,
`property_id` bigint DEFAULT NULL,
`property_name` varchar(255) DEFAULT NULL,
`property_type` varchar(50) DEFAULT NULL,
`asi` bigint NOT NULL,
`created_at` datetime NOT NULL,
`capture_time_relative` decimal(15,4) DEFAULT NULL,
`last_event_id` bigint DEFAULT NULL,
`last_event_name` varchar(100) DEFAULT NULL,
`last_message_id` bigint DEFAULT NULL,
`last_message_name` varchar(100) DEFAULT NULL,
`last_tag_id` bigint DEFAULT NULL,
`last_tag_name` varchar(100) DEFAULT NULL,
`is_crash` tinyint DEFAULT NULL,
`is_anr` tinyint DEFAULT NULL,
`is_ragetap` tinyint DEFAULT NULL,
`last_error_type_id` bigint DEFAULT NULL,
`last_error_type` varchar(100) DEFAULT NULL,
`screen_id` bigint DEFAULT NULL,
`screen_name` varchar(100) DEFAULT NULL,
`last_screen_id` bigint DEFAULT NULL,
`last_screen_name` varchar(100) DEFAULT NULL,
`user_task_id` bigint DEFAULT NULL,
`ue_id` bigint DEFAULT NULL,
PRIMARY KEY (`asi`,`seq_no`,`created_at`,`app_version_id`),
UNIQUE KEY `unique_asi_seq_no` (`asi`,`seq_no`),
KEY `seq_no_date` (`seq_no`,`created_at`),
KEY `last_ids` (`last_screen_id`,`last_event_id`),
KEY `idx_seq_created_asi`(seq_no,created_at,asi),
KEY `created_at` (`created_at`),
KEY `idx_combo` (`seq_no`,`property_id`,`property_name`,`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Table: user_tasks_metadata
Create Table: CREATE TABLE `user_tasks_metadata` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_task_id` bigint NOT NULL,
`device_id` bigint NOT NULL,
`custom_user_id` bigint DEFAULT NULL,
`asi` bigint NOT NULL DEFAULT '0',
`session_id` varchar(300) DEFAULT NULL,
`model` bigint DEFAULT NULL,
`api_level` varchar(300) DEFAULT NULL,
`app_version_id` bigint NOT NULL DEFAULT '0',
`os_version` bigint DEFAULT NULL,
`location` bigint DEFAULT NULL,
`connection_speed` varchar(10) DEFAULT NULL,
`network_operator` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL,
`config_response` tinyint DEFAULT '1',
`total_internal_memory` double(12,5) DEFAULT NULL,
`available_internal_memory` double(12,5) DEFAULT NULL,
`total_ram` double(12,5) DEFAULT NULL,
`available_ram` double(12,5) DEFAULT NULL,
`framework` varchar(45) DEFAULT '',
`ue_sdk_version` mediumint DEFAULT NULL,
`crash_type` bigint DEFAULT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_profile_id` bigint DEFAULT NULL,
`associated_custom_user_id` bigint DEFAULT NULL,
`first_usr_interaction` bigint DEFAULT NULL,
`app_launch_type` varchar(45) DEFAULT '',
`app_launch_time` bigint DEFAULT '0',
PRIMARY KEY (`id`),
KEY `session_metadata_filter_idx` (`custom_user_id`,`device_id`),
KEY `usertask_fk_idx` (`user_task_id`),
KEY `idx_app_version` (`app_version_id`),
KEY `asi_idx` (`asi`),
KEY `device_id` (`device_id`),
KEY `user_profile_id` (`user_profile_id`),
KEY `id_asi` (`user_task_id`,`asi`),
KEY `asi` (`asi`)
) ENGINE=InnoDB AUTO_INCREMENT=2252872743 DEFAULT CHARSET=latin1
Table: user_tasks
Create Table: CREATE TABLE `user_tasks` (
`id` bigint NOT NULL AUTO_INCREMENT,
`app_id` bigint NOT NULL,
`status` tinyint NOT NULL DEFAULT '0',
`app_version` varchar(100) DEFAULT NULL,
`platform` tinyint NOT NULL DEFAULT '1',
`exception_type` tinyint NOT NULL DEFAULT '0',
`error_count` smallint NOT NULL DEFAULT '0',
`crash_type` varchar(300) DEFAULT NULL,
`crash_log` varchar(300) DEFAULT NULL,
`avg_signal_level` int DEFAULT '0',
`is_read` tinyint(1) NOT NULL DEFAULT '0',
`is_important` tinyint(1) NOT NULL DEFAULT '0',
`is_video_available` tinyint(1) NOT NULL DEFAULT '0',
`is_video_played` tinyint(1) NOT NULL DEFAULT '0',
`is_ex` tinyint(1) NOT NULL DEFAULT '0',
`is_ragetap` tinyint(1) NOT NULL DEFAULT '0',
`session_start_time` datetime DEFAULT NULL,
`network_type` tinyint NOT NULL DEFAULT '0',
`s3_video_url` varchar(255) DEFAULT NULL,
`image_format` tinyint DEFAULT '0',
`ue_release_version` smallint NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`batch_created_at` datetime DEFAULT NULL,
`sys_creation_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `session_filter_idx_2` (`app_id`,`platform`,`created_at`,`exception_type`,`app_version`),
KEY `batch_created_idx` (`app_id`,`platform`,`batch_created_at`),
KEY `app_id_created_at` (`app_id`,`created_at`),
KEY `id_app_id` (`app_id`),
KEY `idx_ir` (`is_ragetap`)
) ENGINE=InnoDB AUTO_INCREMENT=1648177712 DEFAULT CHARSET=latin1
rewritten query;
with cte1 as (
select asi,count(1) as rage_tap
from ue_summary.summary_funnel_1066
where s.seq_no = 1
and s.created_at between '2022-09-27 00:00:00' and '2022-10-27 00:00:00'
),
cte2 as (
select id, count(*) 'rage_tap1'
from user_tasks ut where is_ragetap = 1
)
select cte1.*,cte2.* from cte1
inner join user_tasks_metadata utm on utm.asi = cte1.asi
inner join cte2 on b.id = utm.user_task_id
I need like below output;
+----------+
| rage_tap |
+----------+
| 1812564 |
+----------+
It takes time to search so I choose cte, I have tried with subquery but it does not work and it takes around 30 sec - 1.14 min.
as per this, I have indexed the column but also takes time : slow performance of query and scanning many rows
is there any other way to optimize it?
This is your query with two CTEs. The aggregation takes place after the tables after the joins, just as in the original query.
with s as
(
select *
from ue_summary.summary_funnel_1066
where seq_no = 1
and created_at >= date '2022-09-27'
and created_at < date '2022-10-27'
)
, ut as
(
select *
from user_tasks
where is_ragetap = 1
)
select count(*) as rage_tap
from s
join user_tasks_metadata utm on utm.asi = s.asi
join ut on ut.id = utm.user_task_id;
As created_at is a datetime, you should not use BETWEEN, but >= and <. Please check if the date range that I put in my query matches your requirements. It excludes 2022-10-27. If you want to include it, change this to and created_at < date '2022-10-28'.
select id, count(*) 'rage_tap1'
from user_tasks ut where is_ragetap = 1
does not make sense. There is an aggregate (COUNT(*)) but no GROUP BY. Were you showing to get one row? If so, which row? GROUP BY id does not make since id is Unique.
DOUBLE(m,n) is worse than simply DOUBLE. In fact, (m,n) is going away in 8.0 for FLOAT and DOUBLE.
When you have INDEX(a,b), you don't need INDEX(a).
count(1) as rage_tap is done after the JOINs, so it may have an inflated value. Did you do a sanity check?
utm has two indexes on asi. Toss both and add INDEX(asi, user_task_id)
As for turning the Joins into Ctes, go back to when you envisioned the query. You probably said "I need this stuff from this table", then "that stuff from that table", and finally "put things together this way". If you can go back to that thought process, you have the CTEs. (I don't have any idea what the data means or what the goal is, so I cannot reproduce that thought process.)

slow performance of query and scanning many rows

The below query is taking 6.18 min to execute for one row and the cardinality value for the exception_type = 1 is 3, I don't know how to improve the performance.
Query;
select count(1) as rage_tap
from summary_funnel_1066 s
join user_tasks_metadata utm on utm.asi = s.asi
join user_tasks ut on ut.id = utm.user_task_id
where s.seq_no = 1
and s.created_at between '2022-09-27 00:00:00' and '2022-10-27 00:00:00'
and ut.exception_type = 1
explain plan;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ut
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 129554700
filtered: 10.00
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: utm
partitions: NULL
type: ref
possible_keys: usertask_fk_idx,asi_idx,id_asi,asi
key: usertask_fk_idx
key_len: 8
ref: ue_stage.ut.id
rows: 1
filtered: 100.00
Extra: NULL
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: s
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,unique_asi_seq_no,seq_no_date,created_at,idx_combo
key: unique_asi_seq_no
key_len: 12
ref: ue_stage.utm.asi,const
rows: 1
filtered: 50.00
Extra: Using where; Using index
table structure;
Create Table: CREATE TABLE `summary_funnel_1066` (
`funnel_id` int DEFAULT NULL,
`app_id` int DEFAULT NULL,
`platform` int DEFAULT NULL,
`app_version_id` int NOT NULL,
`seq_no` int NOT NULL,
`property_id` bigint DEFAULT NULL,
`property_name` varchar(255) DEFAULT NULL,
`property_type` varchar(50) DEFAULT NULL,
`asi` bigint NOT NULL,
`created_at` datetime NOT NULL,
`capture_time_relative` decimal(15,4) DEFAULT NULL,
`last_event_id` bigint DEFAULT NULL,
`last_event_name` varchar(100) DEFAULT NULL,
`last_message_id` bigint DEFAULT NULL,
`last_message_name` varchar(100) DEFAULT NULL,
`last_tag_id` bigint DEFAULT NULL,
`last_tag_name` varchar(100) DEFAULT NULL,
`is_crash` tinyint DEFAULT NULL,
`is_anr` tinyint DEFAULT NULL,
`is_ragetap` tinyint DEFAULT NULL,
`last_error_type_id` bigint DEFAULT NULL,
`last_error_type` varchar(100) DEFAULT NULL,
`screen_id` bigint DEFAULT NULL,
`screen_name` varchar(100) DEFAULT NULL,
`last_screen_id` bigint DEFAULT NULL,
`last_screen_name` varchar(100) DEFAULT NULL,
`user_task_id` bigint DEFAULT NULL,
`ue_id` bigint DEFAULT NULL,
PRIMARY KEY (`asi`,`seq_no`,`created_at`,`app_version_id`),
UNIQUE KEY `unique_asi_seq_no` (`asi`,`seq_no`),
KEY `seq_no_date` (`seq_no`,`created_at`),
KEY `last_ids` (`last_screen_id`,`last_event_id`),
KEY `created_at` (`created_at`),
KEY `idx_combo` (`seq_no`,`property_id`,`property_name`,`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Table: user_tasks_metadata
Create Table: CREATE TABLE `user_tasks_metadata` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_task_id` bigint NOT NULL,
`device_id` bigint NOT NULL,
`custom_user_id` bigint DEFAULT NULL,
`asi` bigint NOT NULL DEFAULT '0',
`session_id` varchar(300) DEFAULT NULL,
`model` bigint DEFAULT NULL,
`api_level` varchar(300) DEFAULT NULL,
`app_version_id` bigint NOT NULL DEFAULT '0',
`os_version` bigint DEFAULT NULL,
`location` bigint DEFAULT NULL,
`connection_speed` varchar(10) DEFAULT NULL,
`network_operator` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL,
`config_response` tinyint DEFAULT '1',
`total_internal_memory` double(12,5) DEFAULT NULL,
`available_internal_memory` double(12,5) DEFAULT NULL,
`total_ram` double(12,5) DEFAULT NULL,
`available_ram` double(12,5) DEFAULT NULL,
`framework` varchar(45) DEFAULT '',
`ue_sdk_version` mediumint DEFAULT NULL,
`crash_type` bigint DEFAULT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_profile_id` bigint DEFAULT NULL,
`associated_custom_user_id` bigint DEFAULT NULL,
`first_usr_interaction` bigint DEFAULT NULL,
`app_launch_type` varchar(45) DEFAULT '',
`app_launch_time` bigint DEFAULT '0',
PRIMARY KEY (`id`),
KEY `session_metadata_filter_idx` (`custom_user_id`,`device_id`),
KEY `usertask_fk_idx` (`user_task_id`),
KEY `idx_app_version` (`app_version_id`),
KEY `asi_idx` (`asi`),
KEY `device_id` (`device_id`),
KEY `user_profile_id` (`user_profile_id`),
KEY `id_asi` (`user_task_id`,`asi`),
KEY `asi` (`asi`)
) ENGINE=InnoDB AUTO_INCREMENT=2252872743 DEFAULT CHARSET=latin1
Table: user_tasks
Create Table: CREATE TABLE `user_tasks` (
`id` bigint NOT NULL AUTO_INCREMENT,
`app_id` bigint NOT NULL,
`status` tinyint NOT NULL DEFAULT '0',
`app_version` varchar(100) DEFAULT NULL,
`platform` tinyint NOT NULL DEFAULT '1',
`exception_type` tinyint NOT NULL DEFAULT '0',
`error_count` smallint NOT NULL DEFAULT '0',
`crash_type` varchar(300) DEFAULT NULL,
`crash_log` varchar(300) DEFAULT NULL,
`avg_signal_level` int DEFAULT '0',
`is_read` tinyint(1) NOT NULL DEFAULT '0',
`is_important` tinyint(1) NOT NULL DEFAULT '0',
`is_video_available` tinyint(1) NOT NULL DEFAULT '0',
`is_video_played` tinyint(1) NOT NULL DEFAULT '0',
`is_ex` tinyint(1) NOT NULL DEFAULT '0',
`is_ragetap` tinyint(1) NOT NULL DEFAULT '0',
`session_start_time` datetime DEFAULT NULL,
`network_type` tinyint NOT NULL DEFAULT '0',
`s3_video_url` varchar(255) DEFAULT NULL,
`image_format` tinyint DEFAULT '0',
`ue_release_version` smallint NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`batch_created_at` datetime DEFAULT NULL,
`sys_creation_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `session_filter_idx_2` (`app_id`,`platform`,`created_at`,`exception_type`,`app_version`),
KEY `batch_created_idx` (`app_id`,`platform`,`batch_created_at`),
KEY `app_id_created_at` (`app_id`,`created_at`),
KEY `id_app_id` (`app_id`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1636224717 DEFAULT CHARSET=latin1
is there any way possible to improve the performance of the query?
fdsfdfjdnfkjdkjfnkjdnjkfndkjnfjkndjkfnkjdnsfkjndsjknf
Indexes:
utm: INDEX(asi, user_task_id)
s: INDEX(seq_no, created_at, asi)

mysql Query optimization task

Mentioned below is the query and the tables its is being run on ...
SELECT * FROM
tfl_acquistions a,
tfl_property_attributes b WHERE
a.id = b.property_id AND
attribute_id ='111' AND
a.id ='53a8288c03a6823';
Table tfl_acquistions
CREATE TABLE `tfl_acquistions` (
`id` VARCHAR(32) NOT NULL DEFAULT '',
`address` VARCHAR(100) NOT NULL DEFAULT '',
`city` VARCHAR(50) NOT NULL DEFAULT '',
`state` VARCHAR(10) NOT NULL DEFAULT '',
`zip` VARCHAR(10) NOT NULL DEFAULT '',
`county` VARCHAR(50) NOT NULL DEFAULT '',
`country` VARCHAR(50) NOT NULL DEFAULT '',
`status` ENUM('Y','N') NOT NULL DEFAULT 'Y',
`customer_case` VARCHAR(25) NOT NULL DEFAULT '',
`circle_id` INT(11) NOT NULL DEFAULT '0',
`visneta_id` VARCHAR(45) NOT NULL DEFAULT '',
`add_date` DATE NOT NULL DEFAULT '0000-00-00',
`apt_no` VARCHAR(10) NOT NULL DEFAULT '',
`profile_picture` VARCHAR(256) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
INDEX `address` (`address`),
INDEX `city` (`city`),
INDEX `state` (`state`),
INDEX `zip` (`zip`),
INDEX `status` (`status`),
INDEX `customer_case` (`customer_case`),
INDEX `circle_id` (`circle_id`),
INDEX `visneta_id` (`visneta_id`)
)
Table tfl_property_attributes
CREATE TABLE `tfl_property_attributes` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`property_id` VARCHAR(32) NOT NULL,
`attribute_id` INT(11) NOT NULL DEFAULT '0',
`value` VARCHAR(500) NOT NULL DEFAULT '',
`update_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`update_by` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
INDEX `attribute_id` (`attribute_id`),
INDEX `property_id` (`property_id`),
INDEX `property_id_2` (`property_id`, `attribute_id`)
)
I am on a task to optimized this query and i am new .... any help is appreciated
Try:
SELECT * FROM
tfl_acquistions a JOIN
tfl_property_attributes b ON a.id = b.property_id WHERE
b.property_id = '53a8288c03a6823' AND b.attribute_id = '111';
This way MySQL will be able to use the index property_id_2 (property_id, attribute_id) you have created on the second table. Currently, it can't use any indexes.
Try putting EXPLAIN keyword in front of queries to see how MySQL plans to perform them, you'll see that your previous query does not use any index.

MySQL Enhancing Performance without Cache

I am using MySQL version 5.5.14 to run the following query from a table of 5 Million rows:
SELECT P.ID, P.Type, P.Name, P.cty
, X(P.latlng) as 'lat', Y(P.latlng) as 'lng'
, P.cur, P.ak, P.tn, P.St, P.Tm, P.flA, P.ldA, P.flN
, P.lv, P.bd, P.bt, P.nb
, P.ak * E.usD as 'usP'
FROM PIG P
INNER JOIN EEL E
ON E.cur = P.cur
WHERE act='1'
AND flA >= '1615'
AND ldA >= '0'
AND yr >= (YEAR(NOW()) - 100)
AND lv >= '0'
AND bd >= '3'
AND bt >= '2'
AND nb <= '5'
AND cDate >= NOW()
AND MBRContains(LineString( Point(-65.6583, -87.8906)
, Point(65.6583, 87.8906)
), latlng)
AND Type = 'g'
AND tn = 'l'
AND St + Tm - YEAR(NOW()) >= '30'
HAVING usP BETWEEN 300/2 AND 300 LIMIT 100;
The table definitions are:
CREATE TABLE `PIG` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Email` char(50) NOT NULL,
`Type` char(1) NOT NULL,
`Name` char(25) DEFAULT NULL,
`cty` char(2) DEFAULT NULL,
`latlng` point NOT NULL,
`tn` char(1) NOT NULL DEFAULT 'l',
`St` smallint(4) unsigned NOT NULL DEFAULT '0',
`Tm` smallint(3) unsigned NOT NULL DEFAULT '0',
`yr` smallint(4) unsigned NOT NULL DEFAULT '0',
`flA` mediumint(6) unsigned NOT NULL DEFAULT '0',
`ldA` mediumint(6) unsigned NOT NULL DEFAULT '0',
`flN` smallint(3) unsigned NOT NULL DEFAULT '1',
`lv` smallint(3) unsigned NOT NULL DEFAULT '0',
`bd` tinyint(2) unsigned NOT NULL DEFAULT '0',
`bt` tinyint(2) unsigned NOT NULL DEFAULT '0',
`nb` tinyint(1) unsigned NOT NULL DEFAULT '9',
`cur` char(3) DEFAULT NULL,
`ak` int(10) unsigned NOT NULL DEFAULT '0',
`Des` tinytext,
`pDate` datetime DEFAULT NULL,
`cDate` date DEFAULT NULL,
`act` tinyint(1) unsigned NOT NULL DEFAULT '0',
`bid` tinyint(3) unsigned NOT NULL DEFAULT '0',
`ab` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `id_ca` (`cty`,`ak`),
SPATIAL KEY `id_latlng` (`latlng`)
) ENGINE=MyISAM AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1
And:
CREATE TABLE `EEL` (
`cur` char(3) NOT NULL,
`usD` decimal(11,10) NOT NULL,
PRIMARY KEY (`cur`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
The following shows the query execution plan:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: P
type: range
possible_keys: id_latlng
key: id_latlng
key_len: 34
ref: NULL
rows: 742873
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: E
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: BS.P.cur
rows: 1
Extra:
This query does not use query cache due to the presence of NOW() function. From my previous posting, I discovered that other forms of cache exist to speed up the query from initial time of 300s down to less than 2s. My question is: "how does one improve the above query time, knowing that the cache won't be of much use since the search criteria for latlng is constantly changing?" Note that a spatial index on latlng has already been built for optimisation purpose.
Cheers, Ben
Good indexes are the ones with high selectivity. Your conditions are mostly range conditions and this poses a limit on the fields that can be used in a composite index.
Possible indexes to investigate (composed from those fields that have an equality check with the addition in the end, of one field with a range check):
(act, Type, tn, flA)
(act, Type, tn, cDate)
(act, Type, tn, nb)
To check selectivity without creating indexes, you could use:
SELECT COUNT(*)
FROM PIG P
WHERE act='1'
AND Type = 'g'
AND tn = 'l'
AND flA >= '1615'
and
SELECT COUNT(*)
FROM PIG P
WHERE act='1'
AND Type = 'g'
AND tn = 'l'
AND cDate >= NOW()
and
SELECT COUNT(*)
FROM PIG P
WHERE act='1'
AND Type = 'g'
AND tn = 'l'
AND nb <= '5'
and compare the output with the 742873 you have from the spatial index.

Weird MySQL query plan: why is this query using temporary & filesort? How to optimize it?

I have a query:
SELECT *
FROM amp_ads,amp_c,amp_c_countries
WHERE
(amp_c.zone = '24' OR amp_c.zone = '25') AND
amp_ads.ad_complete = '1' AND
amp_ads.ad_type = '17' AND
amp_ads.accept = '1' AND
amp_ads.en_w = '1' AND
amp_c.en_u = '1' AND
amp_c.en_w = '1' AND
(amp_c.i_nu>'0' OR amp_c.c_nu>'0' OR amp_c.d_valid_by>'1299341823' OR amp_c.unlimit='1') AND
(amp_c.i_d_max='0' OR amp_c.i_d_nu>'0') AND
(amp_c.c_d_max='0' OR amp_c.c_d_nu>'0') AND
amp_c.t1<'1299341823' AND
amp_c.t2>'1299341823' AND
amp_c.d7 = '1' AND
(amp_c.some_countr = '0' OR (amp_c_countries.country = 'ES' AND amp_c.n = amp_c_countries.ad AND amp_c.camp = amp_c_countries.c)) AND
amp_c.n = amp_ads.n AND
amp_ads.def = 0
ORDER BY amp_c.price_c desc LIMIT 1
(It's actually not SELECT *, but I simplified the SELECT clause to make it less messy.)
The output of EXPLAIN of the above query is:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: amp_c
type: ref
possible_keys: work,n_index,zone_price
key: zone_price
key_len: 4
ref: const
rows: 79
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: amp_ads
type: eq_ref
possible_keys: n,work
key: n
key_len: 4
ref: advertis_admpro.amp_c.n
rows: 1
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: amp_c_countries
type: index
possible_keys: work
key: work
key_len: 12
ref: NULL
rows: 4083
Extra: Using where; Using index; Using join buffer
1) Why is the 1st table Using temporary and Using filesort? EXPLAIN show that it is using the index zone_price, which is made up of 2 columns: (zone, price_c). So after the index is used to select rows based on the zone value, all the resulting rows are in the order of price_c. And since the query is ORDER BY price_c, there should be no need for Using temporary and Using filesort at all. What am I missing?
2) For the 3rd table, it is supposed to be using the index work. But yet ref is NULL. What does that mean? work is made up of the columns (ad,c,country). So when rows are selected from amp_c_countries using the WHERE clause (amp_c_countries.country = 'ES' AND amp_c.n = amp_c_countries.ad AND amp_c.camp = amp_c_countries.c), shouldn't it be just a simple index lookup? The rows value in EXPLAIN is 4083, amp_c_countries has 4113 rows according to SHOW TABLE STATUS. Does that mean MySQL is doing a full index scan instead of a lookup?
3) Any ideas on how to fix the above 2 problems? amp_ads contains TEXT columns, so a lot of disk temp tables are being created:
| Created_tmp_disk_tables | 906952 |
| Created_tmp_files | 11 |
| Created_tmp_tables | 912227 |
show processlist also shows many processes are in the state of Copying to tmp table.
Thanks. Appreciate your help.
EDIT:
Outputs of SHOW CREATE TABLE:
mysql> SHOW CREATE TABLE `advertis_admpro`.`amp_c`\G
*************************** 1. row ***************************
Table: amp_c
Create Table: CREATE TABLE `amp_c` (
`n` int(10) unsigned NOT NULL DEFAULT '0',
`camp` tinyint(3) unsigned NOT NULL DEFAULT '0',
`zone` int(11) NOT NULL DEFAULT '0',
`javascript` tinyint(1) NOT NULL DEFAULT '0',
`banner_target` varchar(50) NOT NULL DEFAULT '',
`accept` tinyint(1) NOT NULL DEFAULT '0',
`en_u` tinyint(1) NOT NULL DEFAULT '0',
`en_w` tinyint(1) NOT NULL DEFAULT '0',
`i_got` int(10) unsigned NOT NULL DEFAULT '0',
`c_got` int(10) unsigned NOT NULL DEFAULT '0',
`r` double(4,2) unsigned NOT NULL DEFAULT '0.00',
`price_i` double(10,6) unsigned NOT NULL,
`price_c` double(10,3) unsigned NOT NULL,
`i_nu` int(11) NOT NULL DEFAULT '0',
`c_nu` int(11) NOT NULL DEFAULT '0',
`unlimit` tinyint(1) NOT NULL DEFAULT '0',
`d_total` int(10) unsigned NOT NULL DEFAULT '0',
`d_valid_by` int(10) unsigned NOT NULL DEFAULT '0',
`t1` int(10) unsigned NOT NULL DEFAULT '0',
`t2` int(10) unsigned NOT NULL DEFAULT '0',
`d1` tinyint(1) NOT NULL DEFAULT '0',
`d2` tinyint(1) NOT NULL DEFAULT '0',
`d3` tinyint(1) NOT NULL DEFAULT '0',
`d4` tinyint(1) NOT NULL DEFAULT '0',
`d5` tinyint(1) NOT NULL DEFAULT '0',
`d6` tinyint(1) NOT NULL DEFAULT '0',
`d7` tinyint(1) NOT NULL DEFAULT '0',
`tz1` tinyint(1) NOT NULL DEFAULT '0',
`tz2` tinyint(1) NOT NULL DEFAULT '0',
`tz3` tinyint(1) NOT NULL DEFAULT '0',
`tz4` tinyint(1) NOT NULL DEFAULT '0',
`tz5` tinyint(1) NOT NULL DEFAULT '0',
`some_countr` tinyint(1) NOT NULL DEFAULT '0',
`i_d_max` int(10) unsigned NOT NULL DEFAULT '0',
`c_d_max` int(10) unsigned NOT NULL DEFAULT '0',
`i_d_nu` int(10) unsigned NOT NULL DEFAULT '0',
`c_d_nu` int(10) unsigned NOT NULL DEFAULT '0',
`last` int(10) unsigned NOT NULL DEFAULT '0',
`user` int(10) unsigned NOT NULL DEFAULT '0',
`username` varchar(15) NOT NULL DEFAULT '',
`emailed` int(10) unsigned NOT NULL DEFAULT '0',
KEY `work` (`en_u`,`en_w`,`i_nu`,`c_nu`,`d_valid_by`,`unlimit`,`i_d_max`,`c_d_max`,`i_d_nu`,`c_d_nu`,`t1`,`t2`,`n`),
KEY `n_index` (`n`,`camp`),
KEY `zone_price` (`zone`,`price_c`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SHOW CREATE TABLE `advertis_admpro`.`amp_ads`\G
*************************** 1. row ***************************
Table: amp_ads
Create Table: CREATE TABLE `amp_ads` (
`n` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`ad_type` int(10) unsigned NOT NULL DEFAULT '0',
`accept` tinyint(1) NOT NULL DEFAULT '0',
`en_w` tinyint(1) NOT NULL DEFAULT '0',
`weight` tinyint(1) NOT NULL DEFAULT '0',
`w` smallint(5) unsigned NOT NULL DEFAULT '0',
`h` smallint(5) unsigned NOT NULL DEFAULT '0',
`norepeat` int(10) unsigned NOT NULL DEFAULT '0',
`campaigns` tinyint(1) unsigned NOT NULL DEFAULT '0',
`zones` text NOT NULL,
`keywords` text NOT NULL,
`banner` varchar(255) NOT NULL DEFAULT '',
`url` varchar(255) NOT NULL DEFAULT '',
`alt` varchar(255) NOT NULL DEFAULT '',
`raw` text NOT NULL,
`kind` varchar(40) NOT NULL DEFAULT '',
`javascript` tinyint(1) NOT NULL DEFAULT '0',
`ad_complete` tinyint(1) NOT NULL DEFAULT '0',
`url1` text NOT NULL,
`url2` text NOT NULL,
`url3` text NOT NULL,
`text1` text NOT NULL,
`text2` text NOT NULL,
`text3` text NOT NULL,
`text4` text NOT NULL,
`text5` text NOT NULL,
`text6` text NOT NULL,
`text7` text NOT NULL,
`text8` text NOT NULL,
`text9` text NOT NULL,
`text10` text NOT NULL,
`picture1` varchar(255) NOT NULL DEFAULT '',
`picture2` varchar(255) NOT NULL DEFAULT '',
`picture3` varchar(255) NOT NULL DEFAULT '',
`picture4` varchar(255) NOT NULL DEFAULT '',
`picture5` varchar(255) NOT NULL DEFAULT '',
`created` int(10) unsigned NOT NULL DEFAULT '0',
`user` int(11) NOT NULL DEFAULT '0',
`username` varchar(15) NOT NULL DEFAULT '',
`preview` text NOT NULL,
`def` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `n` (`n`),
KEY `work` (`ad_type`,`accept`,`en_w`,`norepeat`,`ad_complete`,`def`)
) ENGINE=InnoDB AUTO_INCREMENT=1532 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SHOW CREATE TABLE `advertis_admpro`.`amp_c_countries`\G
*************************** 1. row ***************************
Table: amp_c_countries
Create Table: CREATE TABLE `amp_c_countries` (
`ad` int(10) unsigned NOT NULL DEFAULT '0',
`c` tinyint(3) unsigned NOT NULL DEFAULT '0',
`country` varchar(5) NOT NULL DEFAULT '',
KEY `work` (`ad`,`c`,`country`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
In order to prevent the need for sorting, when sorting according to the index's second part, the first part must remain constant.
In your case, the condition for the first part is amp_c.zone = '24' OR amp_c.zone = '25', which may not be good enough.
Try changing the condition to amp_c.zone = '24' only, see if that changes the explain (Obviously you will not get all the results you need, but do it to validate my guess)...
If it works and the explain isn't showing using filesort again, you have 2 options:
Sort by all parts of the index: ORDER BY amp_c.zone, amp_c.price_c.
Have only one condition on the zone column, and union with another similar query for the second condition, something like:
(SELECT ... WHERE zone = 24 ... ORDER BY price_c)
UNION
(SELECT ... WHERE zone = 25 ... ORDER BY price_c)
ORDER BY price_c