I wish to do some optimizations on my SQL queries.
Without doing a performance test for it, what query is the most time-consuming ? I am almost sure they return the same result.
!MyClass.find(:first, :conditions => c).nil?
MyClass.count(:conditions => c) > 0
MyClass.count(:conditions => c, :limit => 1) > 0
Regards
You can test it for your own. Writing a performance test with less then 15 lines of code. For more information:
http://guides.rubyonrails.org/performance_testing.html
I ask the question because I thought the answer was an evidence. It appears not.
So I do some average time for several queries. Here is the result, ordered by time :
.count(:conditions => c, :limit => 1) > 0;
=> 0.042037
.count(:conditions => c) > 0
=> 0.037781
.count(:select => '1', :conditions => c) > 0
=> 0.035976
.count(:select => '1', :conditions => c, :limit => 1) > 0
=> 0.034157
.find(:first, :conditions => c).nil?
=> 0.000377
.find(:first, :select => '1', :conditions => c).nil?
( equivalent to .exists?(c) )
=> 0.000184
The last one is the most efficient. Thanks for the tip of :select => '1' !
Related
I have 3 Entities:
Appointment
Doctor (extend fe_users)
Specialization
Dependencies:
Each appointment has exactly one doctor
Each doctor has at least one specialization
Each appointment has at least one specialization - but it can't be
one that its doctor doesn't have
My goal: After a doctor is selected you can choose which specialization of the doctor will be used in order to categorize the appointment - but multiselect should also be possible.
Edit: I came up with this sql to make it clearer what I want in my Select-Field:
SELECT s.name
FROM
tx_appointments_domain_model_specialization s,
fe_users fe,
tx_appointments_doctor_specialization_mm ds,
WHERE fe.username = "###REC_FIELD_doctor###"
AND ds.uid_local = fe.uid
AND s.uid = ds.uid_foreign;
So the part of my TCA of Appointment looks like this now:
It's pretty much all generated by the extension builder except the 'foreign_table_where' in doctor which I found out somehow. But I can't wrap my head around how to set the specialization now.
'doctor' => array(
'exclude' => 1,
'label' => 'doctor',
'config' => array(
'type' => 'select',
'foreign_table' => 'fe_users',
'foreign_table_where' => "AND FIND_IN_SET('1', fe_users.usergroup) ORDER BY fe_users.last_name ASC, fe_users.first_name ASC",
'minitems' => 0,
'maxitems' => 1,
),
),
'specialization' => array(
'exclude' => 1,
'label' => 'specialization',
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_appointments_domain_model_specialization',
'MM' => 'tx_appointments_appointment_specialization_mm',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'wizards' => array(
'_PADDING' => 1,
'_VERTICAL' => 1,
'edit' => array(
'module' => array(
'name' => 'wizard_edit',
),
'type' => 'popup',
'title' => 'Edit',
'icon' => 'edit2.gif',
'popup_onlyOpenIfSelected' => 1,
'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
),
'add' => Array(
'module' => array(
'name' => 'wizard_add',
),
'type' => 'script',
'title' => 'Create new',
'icon' => 'add.gif',
'params' => array(
'table' => 'tx_appointments_domain_model_appointment',
'pid' => '###CURRENT_PID###',
'setValue' => 'prepend'
),
),
),
),
),
I know I could use something like 'foreign_table_where' => ..."###REC_FIELD_doctor###"... but I have no idea how the whole SQL should look like to get only the doctor's specializations showing.
And I'll probably have to add something like this in ext_tables.php which I got from this answer similar to my problem:
$TCA['tx_appointments_domain_model_appointment']['ctrl']['requestUpdate'] .= ',doctor';
I am Working on Elastic Search for My current Project. I need a filter for users based on their industries. please look at my code once. and mySql query as follows
SELECT U.* FROM `users` `U`
JOIN `user_industries` `UI` ON `UI`.`user_id`=`U`.`id`
WHERE `UI`.`industry_id` IN('1','3','5');
$query = array("from" => $start,
"size" => $recordslimit,
"sort" => array(array('id' => 'desc')),
"query" => array(
"filtered" => array(
"query" => array("match_all" => array()),
"filter" => array(
"bool" => array(
'must' => array(array('term' => array('user_type' => 'v')),
array('term' => array('status' => 'a')),
array('term' => array('industries.id' => 1))
),
'must_not' => array(
array('term' => array('subscription_type' => 'n'))
)
))
)));
I passed one Industry Value. how can i pass multiple values of industries
Great start !! You can achieve what you want by using a terms filter instead of a term one and specifying the values 1, 3, 5 in an array():
...
array('terms' => array('industries.id' => array(1, 3, 5)))
...
I need to build WP_Query that will return data from database where both conditions are fulfilled, because of that I'm using AND as relation but returned data are different than I expected. To make it more clear I will post WP_Query arguments here.
Array(
[post_type] => Array
(
[0] => event
)
[post_status] => publish
[paged] => 1
[posts_per_page] => 1000
[tax_query] => Array
(
[relation] => AND
[1] => Array
(
[taxonomy] => event_dates
[field] => slug
[terms] => Array
(
[0] => thursday
[1] => exhibitions
)
)
)
)
With this arguments I thought that I'll get events with type exibition AND are on Thursday.
Thanks in advance for help.
The AND is on the wrong level. The WP_Query arguments should look like something like this:
...
'tax_query' => array(
array(
'taxonomy' => 'event_dates',
'field' => 'slug',
'terms' => array('thursday', 'exhibitions'),
'operator' => 'AND'
)
)
...
Is the following join structure correctly formatted to work with a CakePHP find? This doesn't seem to be working when I use it along with conditions and my gut tells me that the structure is off. I'm new to joins, so any help is appreciated.
'joins' => array(
(int) 0 => array(
'table' => 'cheeses_milk_sources',
'alias' => 'CheesesMilkSource',
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'Cheese.id = CheesesMilkSource.cheese_id'
)
),
(int) 1 => array(
'table' => 'milk_sources',
'alias' => 'MilkSource',
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id' => '1'
)
)
),
'conditions' => array(
'AND' => array(
(int) 0 => array(
'Cheese.cheese_producer_id' => (int) 35
),
(int) 1 => array(
'Cheese.active' => (int) 1
)
)
),
The confusing part is
'conditions' => array(
(int) 0 => 'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id' => '1'
)
You are mixing an array element without a key with one with a key equal to CheesesMilkSource.milk_source_id.
if you need to specify two conditions on the join, do it like
'conditions' => array(
'CheesesMilkSource.milk_source_id = MilkSource.id AND CheesesMilkSource.milk_source_id = 1'
)
perhaps the next snippet will equally work, but I'm not sure and can't test it at the moment - let me know if it does with a comment.
'conditions' => array(
'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id = 1'
)
But since you're joining the tables, maybe you should put CheesesMilkSource.milk_source_id = 1 in the general conditions of the find:
'conditions' => array(
'Cheese.cheese_producer_id' => 35,
'Cheese.active' => 1,
'CheesesMilkSource.milk_source_id' => 1,
)
Notice you don't need to specify AND as this is the default way of joining conditions.
I want my query as:
$conditions = array(
'ManageTrackby.trackby_num NOT LIKE' => '%n/a%',
'Balancesheet.subscriber_id' => $_SESSION['Auth']['User']['subscriber_id'],
'Balancesheet.show_id' => $this->Session->read('openshowid'),
'OR' => array('Balancesheet.season_id' => $season_id, 'Balancesheet.season_id is null'),
'OR' => array('Balancesheet.episode_id'=> $episode_id, 'Balancesheet.episode_id is null')
);
which skips last OR option here and giving below result:
Array
(
[ManageTrackby.trackby_num NOT LIKE] => %n/a%
[Balancesheet.subscriber_id] => 105
[Balancesheet.show_id] => 56
[OR] => Array
(
[Balancesheet.episode_id] => 86
[0] => Balancesheet.episode_id is null
)
)
Here, it misses SEASON_ID from the condition, any idea why?
Please guide me !
Try this. If you want all the first conditions, plus an or of the second conditions, then you will want the OR within the AND array. For complex finds, look up the info on this page http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
$conditions = array(
'AND' => array(
'ManageTrackby.trackby_num NOT LIKE' => '%n/a%',
'Balancesheet.subscriber_id' => $_SESSION['Auth']['User']['subscriber_id'],
'Balancesheet.show_id' => $this->Session->read('openshowid')
)
'OR' => array(
array('Balancesheet.season_id' => $season_id, 'Balancesheet.season_id is null'),
array('Balancesheet.episode_id'=> $episode_id, 'Balancesheet.episode_id is null')
)
)
Your array is setting the OR element twice. Put the two OR statements in their own individual array:
$conditions = array(
'ManageTrackby.trackby_num NOT LIKE' => '%n/a%',
'Balancesheet.subscriber_id' => $_SESSION['Auth']['User']['subscriber_id'],
'Balancesheet.show_id' => $this->Session->read('openshowid'),
array('OR' => array('Balancesheet.season_id' => $season_id, 'Balancesheet.season_id is null')),
array('OR' => array('Balancesheet.episode_id'=> $episode_id, 'Balancesheet.episode_id is null'))
);