Mysql Match…against query performance in InnoDB Mysql 5.6 - mysql

I need to search records in the table which contains millions of records. I have recently updated Mysql version from 5.1 to 5.6.
I was using like in query which was taking around 15 sec to 30 sec.
Currently I have modified query to use MATCH... AGAINST feature of mysql 5.6 INNODB. My query goes like this.
SELECT JOB.IDJOB, JOB.IDEMPLOYER .....
FROM JOB
WHERE ( ( JOB.ITJOBSTARTTYPE=2 AND JOB.DTPLANNEDEND >= '2015-07-06' )
OR ( JOB.ITJOBSTARTTYPE=1
AND ( ( JOB.ITJOBENDTYPE=2 ) OR ( JOB.DTJOBEND>='2015-07-06') )
)
OR ( JOB.ITJOBSTARTTYPE=3
AND ( (JOB.DTJOBEND >='2015-07-06') OR (JOB.ITJOBENDTYPE=2) )
)
)
AND MATCH(VCJOBTITLE, LVJOBCOMPANYDESCRIPTION, VCCOMPANYNAME,
VCSALARYDESC, VCCITY, VCQUALIFICATIONREQUIRED,VCJOBREFERENCE,
LVJOBKEYWORDS )
AGAINST ('test' IN NATURAL LANGUAGE MODE)
ORDER BY JOB.ITJOBBAND ASC,
JOB.VCRANKING DESC,
JOB.IDJOB DESC,
JOB.FJOBWEIGHT ASC
LIMIT 50;
Which takes 80- 120 seconds (3X slower )
If I remove ORDER BY it will load in 6 to 10 sec.
Is their any setting Or performance tunning we can apply here?
Edit: using show create table JOB;
CREATE TABLE `JOB` (
`idJob` int(11) NOT NULL AUTO_INCREMENT,
`idEmployer` int(10) DEFAULT NULL,
`vcJobTitle` varchar(255) NOT NULL,
`lvJobCompanyDescription` text,
`idBasket` int(10) DEFAULT NULL,
`dtActualgolive` datetime DEFAULT NULL COMMENT 'whenever job status become online',
`boImmediatelygolive` int(11) NOT NULL,
`dtRequestedgolive` date DEFAULT NULL,
`dtActualend` datetime DEFAULT NULL COMMENT 'when job is set to be archieved',
`dtPlannedend` date NOT NULL COMMENT 'when posting a job this is calculated. batch will look at this date. date on which regular jobs will be archievd, or date on which internship jobs will be changed to listing',
`dtRequestedend` date DEFAULT NULL COMMENT 'exact date on which employer wants jobs to be archieved',
`dtApplicationdeadline` date DEFAULT NULL COMMENT 'job will be converted to listing on this date',
`boDurationinweeks` int(11) NOT NULL COMMENT 'whether employer gave duration in weeks or not',
`itDurationweeks` int(2) DEFAULT NULL,
`boIsoncredit` int(11) NOT NULL,
`dtCreditend` date DEFAULT NULL,
`fJobbaseprice` float NOT NULL,
`fJobpriceafteradminitemdiscount` float NOT NULL COMMENT 'price after admin item discount',
`fJobpriceafterpromodiscount` float NOT NULL COMMENT 'price after promo discount',
`vcPromotioncode` varchar(50) DEFAULT NULL,
`vcCompanyname` varchar(100) NOT NULL,
`vcSalarydesc` varchar(255) NOT NULL,
`vcCity` varchar(100) NOT NULL,
`vcCounty` varchar(120) DEFAULT NULL,
`vcQualificationrequired` text,
`boWorkfromhome` int(11) NOT NULL,
`boResidential` int(11) NOT NULL,
`boIndoor` int(11) NOT NULL,
`boOutdoor` int(11) NOT NULL,
`boIndoorandoutdoor` int(11) NOT NULL,
`itJobstarttype` int(11) DEFAULT NULL COMMENT 'date,immidiate,always recruiting',
`dtJobstart` date DEFAULT NULL,
`itJobendtype` int(11) DEFAULT NULL COMMENT 'date,ongoing',
`dtJobend` date DEFAULT NULL,
`dtFeaturedstart` date DEFAULT NULL,
`dtFeaturedend` date DEFAULT NULL,
`itFulltimeparttime` int(11) NOT NULL COMMENT 'fulltime,parttime,both',
`boEveningtime` int(11) NOT NULL,
`boDaytime` int(11) NOT NULL,
`boWeekend` int(11) NOT NULL,
`boNewsletter` int(11) NOT NULL,
`vcApplyemail` varchar(500) DEFAULT NULL,
`vcApplyphone` varchar(200) DEFAULT NULL,
`vcApplyaddress` varchar(100) DEFAULT NULL,
`vcApplyURL` varchar(500) DEFAULT NULL,
`boRequirephone` int(11) DEFAULT NULL,
`boRequireaddress` int(11) DEFAULT NULL,
`boRequirecv` int(11) DEFAULT NULL,
`boFeatured` int(11) NOT NULL,
`blLogo` longblob,
`itJobstatus` int(1) DEFAULT NULL COMMENT 'online,offline',
`itEmailedtofriendcount` int(5) DEFAULT NULL COMMENT 'keeps count of how many times users clicked on link email this to friend',
`itDeadlinetype` int(1) DEFAULT NULL,
`idInternshiptypemaster` int(11) DEFAULT NULL,
`vcLengthofscheme` varchar(100) DEFAULT NULL,
`dtInternshiplistingend` date DEFAULT NULL COMMENT 'date when internship job will archieve',
`itJobband` int(2) DEFAULT NULL,
`boGraduate` int(11) NOT NULL,
`boInternship` int(11) NOT NULL,
`boGaptemp` int(11) NOT NULL,
`boParttimeholiday` int(11) NOT NULL,
`boEntrylevel` int(11) NOT NULL DEFAULT '0',
`boHundredPercentDiscountApplicable` int(11) NOT NULL,
`vcContactdetails` varchar(100) DEFAULT NULL,
`vcJobreference` varchar(100) DEFAULT NULL COMMENT 'for importing totaljobs feeds',
`vcJoburlparam` varchar(100) DEFAULT NULL COMMENT 'for importing totaljobs url params',
`dtPutInCurrentBand` datetime DEFAULT NULL COMMENT 'date when job is online and put in band 3',
`itInitcountycount` int(2) NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`lvJobkeywords` text,
`fJobweight` decimal(10,2) DEFAULT '1.00' COMMENT 'Holds the job weight ranging between 0 to 1 (1 being the highest weight)',
`dtReinstatedOn` datetime DEFAULT NULL,
`boIncludeiniframe` int(11) DEFAULT NULL,
`boIsAdvertFeatured` int(11) DEFAULT NULL,
`itincludexml` int(1) DEFAULT '1',
`boAddtojobalert` int(11) DEFAULT '1',
`vcRanking` int(11) DEFAULT '999999',
`itIncludeUkptj` int(11) DEFAULT '1',
PRIMARY KEY (`idJob`),
KEY `JOB_I_1` (`idEmployer`,`itJobstatus`),
KEY `JOB_I_2` (`itJobstatus`,`boGaptemp`,`dtJobstart`),
KEY `JOB_I_3` (`itJobstatus`,`boGraduate`,`dtJobstart`),
KEY `JOB_I_4` (`itJobstatus`,`boInternship`,`dtJobstart`),
KEY `JOB_I_5` (`itJobstatus`,`boParttimeholiday`,`dtJobstart`),
KEY `FI_JOB_idOrder_ORDER_idOrder` (`idBasket`),
KEY `FI_JOB_vcPromotioncode_PROMOTION_vcPromotioncode` (`vcPromotioncode`),
KEY `FI_JOB_idInternshiptype_ITTM_idInternshiptypemaster` (`idInternshiptypemaster`),
KEY `JOB_I_6` (`created_at`),
KEY `boEntrylevel` (`boEntrylevel`),
KEY `itJobband` (`itJobband`),
FULLTEXT KEY `index_ft_search` (`vcJobTitle`,`lvJobCompanyDescription`,`vcCompanyname`,`vcSalarydesc`,`vcCity`,`vcQualificationrequired`,`vcJobreference`,`lvJobkeywords`),
CONSTRAINT `fk_JOB_idEmployer_EMPLOYER_idEmployer` FOREIGN KEY (`idEmployer`) REFERENCES `EMPLOYER` (`idEmployer`),
CONSTRAINT `fk_JOB_idInternshiptype_ITTM_idInternshiptypemaster` FOREIGN KEY (`idInternshiptypemaster`) REFERENCES `INTERNSHIPTYPEMASTER` (`idInternshiptypemaster`),
CONSTRAINT `fk_JOB_idOrder_ORDER_idOrder` FOREIGN KEY (`idBasket`) REFERENCES `BASKET` (`idBasket`),
CONSTRAINT `fk_JOB_vcPromotioncode_PROMOTION_vcPromotioncode` FOREIGN KEY (`vcPromotioncode`) REFERENCES `PROMOTION` (`vcPromotioncode`)
) ENGINE=InnoDB AUTO_INCREMENT=1739324 DEFAULT CHARSET=latin1 |
Edit:
Without sort:
With Sort:

Related

GROUP BY retrieve from the history table the last event

I have 3 tables and I want to retrieve from the history table the last event, so I wrote this request but the result is not good. or am i mistaken? thank you
CREATE TABLE `equipment` (
`id_equipment` int(10) UNSIGNED NOT NULL,
`reference` varchar(32) DEFAULT NULL COMMENT 'clé AIRO2',
`buying_date` date DEFAULT NULL,
`first_use` date DEFAULT NULL,
`checking_delai` varchar(45) DEFAULT NULL,
`serial_number` varchar(256) DEFAULT NULL,
`lot_number` varchar(256) DEFAULT NULL,
`lapsing_date` date NOT NULL,
`status` varchar(32) NOT NULL,
`inspection` date NOT NULL,
`compteur` int(11) DEFAULT NULL,
`id_model` int(10) UNSIGNED DEFAULT NULL,
`updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`detruit` int(1) DEFAULT NULL,
`date_REEPREUVE` date DEFAULT NULL,
`validite_apragaz` date DEFAULT NULL,
`restituee_AJR` int(11) NOT NULL,
`perdu` int(11) DEFAULT NULL,
`maintenance_catt_o2` date DEFAULT NULL,
`vendu` int(11) DEFAULT NULL,
`colonne_inogen` date DEFAULT NULL COMMENT 'date changement colonne inogen',
`rappel_525KS_dec19` int(1) DEFAULT NULL COMMENT 'rappel_cable_DEVILBISS_525_KS'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='matériel';
CREATE TABLE `equipment_history` (
`id_equipment_history` int(10) UNSIGNED NOT NULL,
`id_user` int(10) UNSIGNED NOT NULL,
`id_equipment` int(10) UNSIGNED DEFAULT NULL,
`id_patient` int(11) DEFAULT NULL,
`status` varchar(45) DEFAULT NULL,
`status_date` datetime DEFAULT NULL,
`updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tuyau` tinyint(1) DEFAULT NULL,
`cable_alim` tinyint(1) DEFAULT NULL,
`compteur` int(11) DEFAULT NULL,
`verif_alarme` tinyint(1) DEFAULT NULL,
`verif_volume` tinyint(1) DEFAULT NULL,
`verif_pression` tinyint(1) DEFAULT NULL,
`verif_o2` tinyint(1) DEFAULT NULL,
`verif_debit` tinyint(1) DEFAULT NULL,
`remplacer_consommable` tinyint(1) DEFAULT NULL,
`complet` tinyint(1) DEFAULT NULL,
`comment_panne` text,
`ras` tinyint(1) DEFAULT NULL,
`panne` tinyint(1) DEFAULT NULL,
`id_piece_jointe` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='historique de l''utilisation du matériel';
CREATE TABLE `patient_has_equipment` (
`id_patient_has_equipment` int(10) UNSIGNED NOT NULL,
`id_intervention` int(10) UNSIGNED DEFAULT NULL,
`id_equipment` int(10) UNSIGNED NOT NULL,
`id_patient` int(10) UNSIGNED DEFAULT NULL,
`date_attribution` date DEFAULT NULL,
`id_user` int(11) DEFAULT NULL,
`version_appli` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
request :
SELECT
equipment.id_equipment,
equipment.reference,
history.updated,
history.`status`
FROM
equipment
LEFT JOIN
(
SELECT
*
FROM
`equipment_history`
GROUP BY
id_equipment
ORDER BY
`equipment_history`.`updated`
DESC
) AS history
ON
history.id_equipment = equipment.id_equipment
WHERE
history.`status` = 3 AND equipment.id_equipment NOT IN(
SELECT
id_equipment
FROM
patient_has_equipment
)
thanks
The group by subquery is the problem. While this is a syntax error in most databases, MySQL - unfortunately - tolerates this syntax (when sql mode ONLY_FULL_GROUP_BY is disabled), but does not do what you think: you actually an arbitary record from the table for each equipment_id (the order by clause has no effect on this behavior).
You need to filter for the last history record rather than aggregate. I think that this should do what you want:
select
e.id_equipment,
e.reference,
eh.updated,
eh.status
from equipment e
inner join equipment_history eh on eh.id_equipment = e.id_equipment
where
eh.status = 3
and eh.updated = (
select max(eh1.updated)
from equipment_history eh1
where eh1.id_equipment = e.id_equipment
)
and not exists (
select 1
from patient_has_equipment phe
where phe.id_equipment = e.id_equipment
)

Two MySql tables have correct indexes yet JOIN takes 9 seconds on small tables

mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
I am taking over a project. It is very old and the original programmer is long gone. No one has any idea why certain decisions were made.
The following query runs (on my Mac) in 9.5 seconds but if I remove the last JOIN then it drops to 2.5 seconds. What is wrong with that last JOIN?
select `ttl`.`id` AS `id`,
`ttl`.`name` AS `name`,
`ttl`.`updated_at` AS `last_update_on`,
`ttl`.`user_id` AS `list_creator`,
`ttl`.`retailer_nomination_list` AS `nomination_list`,
`ttl`.`created_at` AS `created_on`,
count(distinct `tlb`.`title_id`) AS `title_count`
from `haha_title_lists` `ttl`
left join `haha_title_list_to_users` `tltu` on((`ttl`.`id` = `tltu`.`title_list_id`))
left join `users` `u` on((`tltu`.`user_id` = `u`.`id`))
left join `users` `u2` on((`tltu`.`user_id` = `u2`.`id`))
left join `haha_title_list_to_venues` `tlv` on((`ttl`.`id` = `tlv`.`title_list`))
left join `haha_venue_properties` `tvp` on((`tlv`.`venue_id` = `tvp`.`id`))
join `haha_title_list_to_books` `tlb` on((`ttl`.`id` = `tlb`.`title_list_id`))
join `wawa_title` `ot` on((`tlb`.`title_id` = `ot`.`title_id`))
group by `ttl`.`id`;
The tables:
CREATE TABLE `haha_title_list_to_books` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title_id` int(11) NOT NULL,
`title_list_id` int(11) NOT NULL,
`sdk` varchar(15) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`created_at` datetime NOT NULL,
`promo_start_date` date DEFAULT NULL,
`promo_end_date` date DEFAULT NULL,
`promo_price` float DEFAULT NULL,
`confirmations` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`nominations` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`title_note` text COLLATE utf8_unicode_ci,
`executed` int(11) DEFAULT NULL,
`event_created` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_promo_start_date` (`promo_start_date`),
KEY `idx_promo_end_date` (`promo_end_date`),
KEY `idx_title_list_to_books_title_id` (`title_id`),
KEY `idx_title_list_to_books_title_list_id` (`title_list_id`)
) ENGINE=MyISAM AUTO_INCREMENT=21847 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
and:
CREATE TABLE `wawa_title` (
`title_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`title_alpha` varchar(25) NOT NULL,
`display_title` varchar(200) NOT NULL,
`subtitle` text NOT NULL,
`sdk10` varchar(13) DEFAULT '',
`sdk13` varchar(15) DEFAULT NULL,
`primary_sdk13` varchar(15) DEFAULT NULL,
`asin` varchar(10) DEFAULT NULL,
`pub_season` varchar(15) NOT NULL,
`pub_year` varchar(15) NOT NULL,
`bisac1` varchar(15) NOT NULL,
`bisac2` varchar(15) NOT NULL,
`bisac3` varchar(15) NOT NULL,
`barcode` varchar(30) DEFAULT NULL,
`dewey_decimal` varchar(15) NOT NULL,
`lib_of_congress` varchar(15) NOT NULL,
`spanish_language` tinyint(4) NOT NULL,
`target_audience` tinyint(3) unsigned DEFAULT NULL,
`language` varchar(20) DEFAULT NULL,
`edition` varchar(45) DEFAULT NULL,
`pages` int(11) DEFAULT NULL,
`number_in_series` int(11) DEFAULT NULL,
`trimsize` varchar(10) DEFAULT NULL,
`filesize` varchar(10) DEFAULT NULL,
`duration_hours` int(11) DEFAULT NULL,
`duration_minutes` int(11) DEFAULT NULL,
`discs` int(11) DEFAULT NULL,
`download` date DEFAULT NULL,
`size_unit` varchar(15) NOT NULL DEFAULT '',
`digitization_date` date NOT NULL,
`us_on_sale_date` date NOT NULL,
`aus_on_sale_date` date NOT NULL,
`can_on_sale_date` date NOT NULL,
`uk_on_sale_date` date NOT NULL,
`us_list_price` varchar(10) NOT NULL,
`aus_list_price` varchar(10) NOT NULL,
`can_list_price` varchar(10) NOT NULL,
`uk_list_price` varchar(10) NOT NULL,
`isPrimary` varchar(1) DEFAULT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modifier` int(11) NOT NULL,
`activated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` varchar(3) NOT NULL DEFAULT 'N',
`flagged_string` text,
`created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`assets_id` varchar(20) DEFAULT NULL,
`book_details` text,
`book_keynote` text,
`exclude_goodreads` char(1) NOT NULL DEFAULT 'N',
`series_description` text,
`review_quote1` text,
`territory_id` int(11) DEFAULT '27',
`featured_newsletter_id` tinyint(3) unsigned DEFAULT '0',
`retailer_discovery_check` datetime DEFAULT NULL,
`suppress_retailer_approval` tinyint(1) DEFAULT '0',
`suppress_retailer_approval_reason` varchar(255) DEFAULT NULL,
`ebb_description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`slug` varchar(150) DEFAULT NULL,
`legacy_slug` varchar(150) DEFAULT NULL,
`us_agency_price` varchar(10) DEFAULT NULL,
`firebrand_title_id` int(11) DEFAULT NULL,
`ebb_label` varchar(200) DEFAULT NULL,
`ebb_end_sale_date` date DEFAULT NULL,
`ebb_downprice` decimal(10,2) DEFAULT NULL,
`book_club` varchar(1) DEFAULT NULL,
`best_seller` varchar(1) DEFAULT NULL,
`award_winner` varchar(1) DEFAULT NULL,
`discovery` char(1) NOT NULL DEFAULT 'Y',
`narrator_id` int(11) DEFAULT NULL,
`suppress_series_data` varchar(255) DEFAULT NULL,
PRIMARY KEY (`title_id`),
KEY `active_index` (`active`),
KEY `fk_title_series_id_idx` (`series_id`),
KEY `series_id` (`series_id`),
KEY `idx_title_sdk13` (`sdk13`),
KEY `idx_title_active_isprimary` (`active`,`isPrimary`),
KEY `bisac1` (`bisac1`),
KEY `bisac2` (`bisac2`),
KEY `bisac3` (`bisac3`),
KEY `idx_primary_sdk13` (`primary_sdk13`),
KEY `idx_territory_id` (`territory_id`),
CONSTRAINT `fk_title_series_id` FOREIGN KEY (`series_id`) REFERENCES `wawa_series` (`series_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=19700 DEFAULT CHARSET=utf8 |
If I remove this line:
join `wawa_title` `ot` on((`tlb`.`title_id` = `ot`.`title_id`))
The query speed drops from 9.5 seconds to 2.5 seconds. Not great, but a huge improvement.
And yet, both tables have indexes on table_id, so why would that line be a problem?
I notice that one table is InnoDB and the other is MyISAM. Would that have an effect?
Do not JOIN to tables that you don't use.
A JOIN often "explodes" the number of rows, then a GROUP BY like you have reels in the number of rows. To see this, leave all the JOINs there, but remove the GROUP BY. See how many rows you get.
To avoid part of that explosion, change
count(distinct `tlb`.`title_id`) AS `title_count`
to
( SELECT count(distinct `title_id`)
FROM `haha_title_list_to_books`
WHERE `ttl`.`id` = `title_list_id`
) AS `title_count`
and remove the current JOIN to tlb.
Mixing MyISAM and InnoDB should not have any direct impact on this SELECT. However, you should consider moving all of your tables to InnoDB.

Long time to exec a simple query in mysql

I am with a performance problem in my MySQL database, and do not know if it's the server configuration issue or disk space, or simply not riding the query correctly.
a simple query that summarizes the total number of rows in a table by a distinct field, it takes more than 3 minutes. The status is "Sending data" for a long time.
the query is as follows:
SELECT COUNT (DISTINCT (ca.nm_slug)) the qtd_total
FROM consulta_atual ca
WHERE ca.cd_categoria_site = 436
below the description of the table (has a 4 million records)
CREATE TABLE IF NOT EXISTS `consulta_atual` (
`cd_categoria` int(11) NOT NULL DEFAULT '0',
`cd_categoria_site` int(11) DEFAULT NULL,
`ds_categoria` varchar(100) NOT NULL,
`ds_subcategoria` varchar(200) NOT NULL,
`cd_produto_price` bigint(11) NOT NULL,
`cd_seq` bigint(20) NOT NULL DEFAULT '0',
`tp_fornecedor` int(11) NOT NULL DEFAULT '0',
`name` varchar(300) NOT NULL,
`nm_slug` varchar(200) DEFAULT NULL,
`fornecedor` int(11) NOT NULL,
`url_img_fornecedor` varchar(200) NOT NULL,
`url_raiz_fornecedor` varchar(200) NOT NULL,
`url_imagem` varchar(500) NOT NULL,
`url_produto` varchar(500) NOT NULL,
`vlr_produto` varchar(49) NOT NULL DEFAULT '',
`pnt_produto` varchar(53) NOT NULL DEFAULT '',
`vlr_produto_original` float(10,2) NOT NULL,
`menor_valor` float DEFAULT NULL,
`maior_valor` float DEFAULT NULL,
`qtd_lojas` int(11) DEFAULT NULL,
PRIMARY KEY (`cd_produto_price`,`fornecedor`),
KEY `nm_slug_2` (`nm_slug`),
KEY `ds_categoria` (`ds_categoria`),
KEY `vlr_produto_original` (`vlr_produto_original`),
KEY `cd_categoria_site` (`cd_categoria_site`),
KEY `fornecedor` (`fornecedor`),
KEY `tp_fornecedor` (`tp_fornecedor`),
FULLTEXT KEY `name` (`name`),
FULLTEXT KEY `ds_categoria_2` (`ds_categoria`),
FULLTEXT KEY `ds_categoria_3` (`ds_categoria`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
How can I improve execution performance of this simple query?

MySQL find a row when the sum of points become bigger than number

I have such sql query
SELECT *,(p.datetime-u.createtime)/86400 as result
FROM tbl_user_points p
Inner join tbl_users u ON u.id=p.user_id
GROUP BY p.user_id
HAVING SUM(p.points) > 100
order by SUM(p.points)
i need to find the datetime( the row in table tbl_user_points), when each users reached.
For more information Here the schemata of table
tbl_user_points
CREATE TABLE `tbl_user_points` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`action` int(10) unsigned NOT NULL,
`description` varchar(255) DEFAULT '',
`points` int(10) NOT NULL DEFAULT '0',
`datetime` int(10) unsigned NOT NULL,
`club_id` int(10) unsigned DEFAULT NULL,
`event_id` int(10) unsigned DEFAULT NULL,
`location_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='Achieved users points for any actions.';
Here the schemata of table
tbl_users
CREATE TABLE `tbl_users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(128) NOT NULL,
`activkey` varchar(128) NOT NULL DEFAULT '',
`createtime` int(11) NOT NULL,
`lastvisit` int(11) NOT NULL,
`superuser` int(1) NOT NULL DEFAULT '0',
`status` int(1) NOT NULL DEFAULT '1',
`first_name` varchar(128) DEFAULT NULL,
`last_name` varchar(128) DEFAULT NULL,
`gender` varchar(6) DEFAULT NULL,
`locale` varchar(45) DEFAULT NULL,
`service` varchar(45) NOT NULL,
`service_id` varchar(255) DEFAULT NULL,
`location` varchar(128) DEFAULT NULL,
`state` int(3) DEFAULT NULL,
`photo` varchar(255) DEFAULT NULL,
`city` varchar(125) DEFAULT NULL,
`about_me` varchar(255) DEFAULT NULL,
`user_code` varchar(10) DEFAULT NULL,
`loyalty_level` varchar(45) DEFAULT 'basic' COMMENT 'Level of loyalty for current user',
`updatetime` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `user_code_UNIQUE` (`user_code`),
KEY `status` (`status`),
KEY `superuser` (`superuser`)
) ENGINE=InnoDB AUTO_INCREMENT=1033 DEFAULT CHARSET=utf8;
sample input
tbl_user_points
id | user_id|action|description|points| datetime
2246 1 1 First visit 5 1383331212
2254 1 2 Second visit 15 1383354853
2255 1 3 Winner 25 1383360231
2256 2 1 First visit 5 1383331202
2257 2 2 Second visit 15 1383354553
2258 2 3 Winner 25 1383360211
tbl_user simple,for example
id=1,createtime=1313000000
id=2,createtime=1313000001
for HAVING SUM(p.points) > 15
output should be
user_id datetime
1 1383354853
2 1383354553
Use CASE syntax. Check this link:
http://dev.mysql.com/doc/refman/5.0/en/case.html.
You can achieve it by using statements like this:
Select X, case when y>100 then desired_row when y<100 then desired_row end as 'desired_row' from your_table where column=your_condition order by 1
Here you're conditioning the select clause by as many cases or conditions you requiere.

n-number of nested inner join

I have a sql-statement which correctly fetches data from one table. However, I need to fetch in the same way from n number of tables named table_n. All of these tables contain a 3-field primary key of projid, docid and revnr. I need to return n as docType as well, to differentiate the tables. The result will be sorted by projid and/or docid.
I tried sorting all the outputs from the different queries in PHP but it was way too slow (at least a few seconds on a 3MB database). I'm convinced MySQL/MSSQL will do it faster.
This is my current query:
SELECT a.* FROM `table_1` a
INNER JOIN (SELECT docid,
Max(revnr) max_val
FROM `table_1`
WHERE ( projid = something )
GROUP BY docid) b
ON a.docid = b.docid
AND a.revnr = b.max_val ORDER BY docid DESC
My current query gets the rows with highest revnr for each docid and projid.
I'm developing on MySQL but I need it to work on MSSQL as well. A general SQL solution would be great.
Thanks!
EDIT: Table schemas of the tables i currently have:
CREATE TABLE IF NOT EXISTS `table_1` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
`ritningsnr` varchar(128) NOT NULL,
`moment` varchar(256) NOT NULL,
`omrade` varchar(256) NOT NULL,
`start` datetime NOT NULL,
`stop` datetime NOT NULL,
`extTodo` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='egenkontroll';
CREATE TABLE IF NOT EXISTS `table_2` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
`extWater` int(11) NOT NULL,
`extRisk` int(11) NOT NULL,
`extSystem` int(11) NOT NULL,
`extHelp` int(11) NOT NULL,
`extProvtryck` int(11) NOT NULL,
`extDoc` int(11) NOT NULL,
`extEgenkontroll` int(11) NOT NULL COMMENT 'exttabell',
`extOther` int(11) NOT NULL,
`extMontorer` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='arbetsberedning';
CREATE TABLE IF NOT EXISTS `table_3` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`adress` varchar(256) NOT NULL,
`pipesMark` tinyint(1) NOT NULL,
`pipesKulvert` tinyint(1) NOT NULL,
`pipesBasement` tinyint(1) NOT NULL,
`pipesVaning` tinyint(1) NOT NULL,
`pipesIngjutna` tinyint(1) NOT NULL,
`ledningTappvatten` tinyint(1) NOT NULL,
`ledningVarmevatten` tinyint(1) NOT NULL,
`ledningHetvatten` tinyint(1) NOT NULL,
`ledningKylaPrim` tinyint(1) NOT NULL,
`ledningKylaSek` tinyint(1) NOT NULL,
`ledningGas` tinyint(1) NOT NULL,
`ledningLuft` tinyint(1) NOT NULL,
`ledningAvlopp` tinyint(1) NOT NULL,
`ledningOther` varchar(512) NOT NULL,
`materialGjutjarn` tinyint(1) NOT NULL,
`materialSteel` tinyint(1) NOT NULL,
`materialKoppar` tinyint(1) NOT NULL,
`materialPlast` tinyint(1) NOT NULL,
`materialRostfritt` tinyint(1) NOT NULL,
`materialOther` varchar(512) NOT NULL,
`omfattningLength` int(11) NOT NULL COMMENT 'meter',
`omfattningDimension` varchar(16) NOT NULL,
`omfattningRitningnr` varchar(128) NOT NULL,
`doneWithPump` tinyint(1) NOT NULL,
`doneWithVattenledning` tinyint(1) NOT NULL,
`doneWithKompressor` tinyint(1) NOT NULL,
`doneWithTathetsprovare` tinyint(1) NOT NULL,
`tryckmedieVatten` tinyint(1) NOT NULL,
`tryckmedieLuft` tinyint(1) NOT NULL,
`tryckmedieOther` varchar(128) NOT NULL,
`manometerDiameter` int(11) NOT NULL COMMENT 'mm',
`manometerGradering` int(11) NOT NULL COMMENT 'kPa',
`manometerReadPressure` int(11) NOT NULL,
`manometerTid` int(11) NOT NULL COMMENT 'sekunder',
`testedOn` datetime NOT NULL,
`testedBy` varchar(128) NOT NULL COMMENT '"id_" + (userid)',
`comments` varchar(1024) NOT NULL,
`commentsBy` varchar(128) NOT NULL COMMENT '"id_" + (userid)',
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
The fields I need are projid, docid, revnr, revname, signedOn, sign and are present in all current and future tables.