Understanding a Slow Query - magento-1.7

I enabled slow query log for my mySQL to observe the slow queries that take more than 10 seconds to be executed. Then I found only one query that is being logged in the mysql.slow_log table. That is:
SELECT `e`.*, IF(at_is_active.value_id > 0, at_is_active.value, at_is_active_default.value) AS `is_active`, IF(at_include_in_menu.value_id > 0, at_include_in_menu.value, at_include_in_menu_default.value) AS `include_in_menu`, `core_url_rewrite`.`request_path` FROM `catalog_category_entity` AS `e`
INNER JOIN `catalog_category_entity_int` AS `at_is_active_default`
ON (`at_is_active_default`.`entity_id` = `e`.`entity_id`)
AND (`at_is_active_default`.`attribute_id` = '42')
AND `at_is_active_default`.`store_id` = 0
LEFT JOIN `catalog_category_entity_int` AS `at_is_active`
ON (`at_is_active`.`entity_id` = `e`.`entity_id`)
AND (`at_is_active`.`attribute_id` = '42')
AND (`at_is_active`.`store_id` = 1)
INNER JOIN `catalog_category_entity_int` AS `at_include_in_menu_default`
ON (`at_include_in_menu_default`.`entity_id` = `e`.`entity_id`)
AND (`at_include_in_menu_default`.`attribute_id` = '67')
AND `at_include_in_menu_default`.`store_id` = 0
LEFT JOIN `catalog_category_entity_int` AS `at_include_in_menu`
ON (`at_include_in_menu`.`entity_id` = `e`.`entity_id`)
AND (`at_include_in_menu`.`attribute_id` = '67')
AND (`at_include_in_menu`.`store_id` = 1)
LEFT JOIN `core_url_rewrite`
ON (core_url_rewrite.category_id=e.entity_id)
AND (core_url_rewrite.is_system=1
AND core_url_rewrite.product_id IS NULL AND core_url_rewrite.store_id='1'
AND id_path LIKE 'category/%')
WHERE (`e`.`entity_type_id` = '3')
AND (`e`.`entity_id` IN('####HERE ARE SOME IDs####'))
AND (IF(at_is_active.value_id > 0, at_is_active.value, at_is_active_default.value) = '1')
AND (IF(at_include_in_menu.value_id > 0, at_include_in_menu.value, at_include_in_menu_default.value) = '1')
It also causing high CPU usage. I observed the log time and CPU monitoring curve on that same time and found that. It is being happened after 9/10 hours gap frequently.
Can you please help me when this query is called/executed by magento so that I can change any settings that is responsible for executing this query?

This can be caused by index catalogue_url
A quick fix is to set all indexing to manual.
Then run this shell script via cron hourly:
php shell/indexer.php --reindex catalog_product_attribute
php shell/indexer.php --reindex catalog_product_price
php shell/indexer.php --reindex tag_summary
php shell/indexer.php --reindex cataloginventory_stock
php shell/indexer.php --reindex catalogsearch_fulltext
php shell/indexer.php --reindex catalog_category_product
php shell/indexer.php --reindex catalog_category_flat
php shell/indexer.php --reindex catalog_product_flat
It indexes all but urls.
Then run this nightly:
<?php
echo "clearing core_url_rewrite so that indexer can repopulate immediately\n";
require_once "/home/path/to/store/app/Mage.php";
umask( 0 );
Mage::App('default');
$resource = Mage::getSingleton('core/resource');
$writeConnection = $resource->getConnection('core_write');
$query = "TRUNCATE `core_url_rewrite`";
$writeConnection->query($query);
echo "cleared\n";
$start = time();
echo "reindexing catalog_url start \n";
$process = Mage::getSingleton('index/indexer')->getProcessByCode('catalog_url');
$process->reindexEverything();
$finish = time() - $start;
echo "reindexing catalog_url finished in ".$finish." seconds \n";
?>

Related

SphinxQL / Sphinx Search: Query to find rows where columns are equal (category1 = category2)?

SphinxSearch: 3.3.1
Ubuntu 22.04
PHP 8.1.12
I am trying to use SphinxQL with PHP to find rows where two different categories match, such as:
$db = new PDO('mysql:host=127.0.0.1;port=9306', '', '');
$sql = "SELECT id FROM index,delta,rtindex WHERE category2 > 0 AND category2 = category1 LIMIT 1000 OPTION max_matches=1000";
$stmt = $db->query($sql);
However, I am receiving a syntax error whenever I do this. I thought this query had worked in the past, but I'm just now noticing it in the logs. Is this the correct way to do it, or is there some other way dictated by sphinx's rules?

PgBadger report from AWS RDS log parsed not fully

I use pgbadger as following:
pgbadger -p %t:%r:%u#%d:[%p]: postgresql.log
log_line_prefix are set for RDS and cannot be changed. Its same that i pass to pgbadger ( %t:%r:%u#%d:[%p]: )
When i launch pgbadger i get following stdout output.
[=======================> ] Parsed 52063631 bytes of 52063634 (100.00%), queries: 66116, events: 0
LOG: Ok, generating html report...
So it parsed queries, and it output i see most of stats. But in Top section i see wrong info. Time consuming queries and Slowest individual queries says "no dataset". And in Most frequent queries (N) all queries have all durations as 0 . See screenshot here : http://clip2net.com/s/3wUxfXg . And examples for query dont show any examples at all.
I checked postgresql log and duration is there. For example:
2016-04-13 22:00:02 UTC:blabla.com(43372):blabla#blabla:[20584]:LOG: statement: SELECT DISTINCT "reports2_report"."id", "reports2_report"."created", "reports2_report"."modified", "reports2_report"."data", "reports2_report"."person_info", "reports2_report"."status", "reports2_report"."source_profile_id", "reports2_report"."application_id", "reports2_report"."error_detail" FROM "reports2_report" INNER JOIN "reports2_reportsourceprofile" ON ( "reports2_report"."source_profile_id" = "reports2_reportsourceprofile"."id" ) INNER JOIN "reports2_reportsource" ON ( "reports2_reportsourceprofile"."report_source_id" = "reports2_reportsource"."id" ) INNER JOIN "applications_applicationdocument" ON ( "reports2_report"."application_id" = "applications_applicationdocument"."slug" ) WHERE ("reports2_reportsource"."identifier" = 'redridge_credit' AND "reports2_report"."application_id" = 'jqLoMe' AND ("reports2_report"."application_id" IN (SELECT DISTINCT V0."slug" FROM "applications_applicationdocument" V0 LEFT OUTER JOIN "auth_user" V1 ON ( V0."seller_id" = V1."id" ) LEFT OUTER JOIN "accounts_companymembership" V2 ON ( V1."id" = V2."user_id" ) LEFT OUTER JOIN "applications_applicationbundle" V5 ON ( V0."bundle_id" = V5."id" ) LEFT OUTER JOIN "applications_applicationbundle_sharees" V6 ON ( V5."id" = V6."applicationbundle_id" ) WHERE (V2."company_id" IN (SELECT U0."id" FROM "accounts_company" U0 WHERE (U0."lft" > 2 AND U0."tree_id" = 6 AND U0."rght" < 3)) OR V0."applicant_id" = 111827 OR V0."seller_id" = 111827 OR V6."user_id" = 111827)) OR "applications_applicationdocument"."seller_id" = 111827 OR "applications_applicationdocument"."applicant_id" = 111827 OR "reports2_reportsourceprofile"."user_id" = 111827)) ORDER BY "reports2_report"."created" DESC LIMIT 20
2016-04-13 22:00:02 UTC:blabla.com(43372):blabla#blabla:[20584]:LOG: duration: 517.047 ms
How to get PgBadger to generate full proper report?
It was due to log_statement = all instead of log_statement=none. log_min_duration_statement works only if log_statement = none

For each loop for a table in OpenEdge 10.2b takes more time

Below for each loop takes more time and i cant able to trace index usage using XREF as the table uses Oracle Schema.Please Help me.
Need to generate report for different Report Type ( Report type is the input parameter in my code ).Single report type may contain more than 50,000 records how to access all the record within minute.Index detail also mentioned below for each loop.
FOR EACH Report
FIELDS(EXTRACTDATE STATUS MailingType ReportType ReportNumber
RequestID CustID)
WHERE Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND (Report.MailingType = "LETTER"
OR Report.MailingType = "Mail") NO-LOCK:
< Statements >
.
.
END.
**Index Detail**
CREATE INDEX "TYPE_IDX1" ON "Report" ("EXTRACTDATE" DESC, "ReportTYPE", "STATUS", "MailingTYPE", "PROGRESS_RECID")
CREATE INDEX "REQ_IDX1" ON "Report" ("REQUESTID", "PROGRESS_RECID")
CREATE INDEX "RTTYP_IDX1" ON "Report" ("ReportTYPE","PROGRESS_RECID")
The "OR" at the end will slow things down considerably - the AVM does better if you split it up into two sets of AND statements and OR the result, like so:
WHERE (Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND Report.MailingType = "LETTER")
OR
(Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND Report.MailingType = "Mail")

zend framework count the number of rows in mysql query

I am new to zend framework
I want to calculate number of rows in my query
this is my code:
$nm = new Zend_Db_Table('emp');
$row = $nm->fetchRow($nm->select()->where('id= ?', $a));
yes you can try in this way to get total number of rows return by your sql query.
$select = $this->select();
$select->where('id= ?', $a);
$result=$this->fetchAll($select);
if(empty($result)){
return false;
}else{
echo "Total number of users : -> ".count($result->toArray());
}
let me know if i can help you more.
If you are testing for the existance of a record by primary key then you can use $nm->find($a) and check for any results.
if you expect the result set to be small then you can do
$nm->fetchAll($nm->select()->where("id = ?", $a);
If you expect the result set to get big and all you are really after is the count then authoring a query that asks for the count of a field would probably make the most sense to keep the query from eating up a lot of server memory:
$row = $nm->getAdapter()->fetchRow("select count(*) as num_rows".
" from ".$nm->info(Zend_Db_Table_Row_Abstract::NAME).
" where ".$nm->getAdapter()->quoteInto("id = ?", $a));
echo "Users ".$row["num_rows"];
In Zend Framework 1, you can use count() function at the last of query for getting total number of rows in the table.
For example:
$row = $nm->fetchAll($nm->select()->where('id = ?', $a ))->count();
NOTE: This will only return total number of rows in the table. Output is Integer.

Best way to use Perl's DBI to UPDATE a row, and print the response to the cmd-line?

Have some Perl code which is using the DBI module - (the code is at work, I can post it in the morning if needed) - but mainly trying to get a sense of what DBI needs to do an update to a row -- and get either errors back, or confirmation that the UPDATE was executed.
(Below is just a basic example, feel free to give your own example and sample DDL if you want... just want some code that I know works. I've run my code via the Perl PtkDB debugger, and can "see" the SQL it generating and executing -- even paste in in the MySQL consol and execute it... but it's doing nothing in the Perl, even thought the select statements are working. Mainly just want a better idea of how DBI is handling UPDATE to MySQL, and if there's any built in feature in DBI that would make debugging this more simple. Thanks!)
So, please supply one full Perl script that:
Sets the connection (MySQL)
SELECT row two based on ID and get the first and last name
Lowercase the names
UPDATE the table
disconnect
Sample TABLE
<COL01>Id <COL02>FirstName <COL03>LastName
<ROW01-COL01>1 <ROW01-COL02>John <ROW01-COL03>Smith
<ROW02-COL01>2 <ROW02-COL02>Jane <ROW02-COL03>Doe
UPDATE (1): Code in question is below. The ONLY thing I've changed is remove code not related to the issue and the config info (eg database name, user, password, etc.) and made the value production for the variables super simple. This code was created by someone else and in a legacy code base.
use strict;
use warnings;
use DBI;
sub dbOpen {
my $dsn;
my $dbh;
$dsn = "DBI:mysql:database=databasename;host=localhost;port=3306";
$dbh = DBI->connect( $dsn, "root", "password" ) ||
print STDERR "FATAL: Could not connect to database.\n$DBI::errstr\n";
$dbh->{ AutoCommit } = 0;
return($dbh);
} # END sub dbOpen
my $Data;
$Data = &dbOpen();
my ($sql,$rs,$sql_update_result);
my $column2,
my $column3;
my $id;
$column2 = 2,
$column3 = 3;
$id = 1;
$sql = "UPDATE table SET column1 = NULL, column2 = ".$column2.", column3 = ".$column3." WHERE id = ".$id.";";
$rs = $Data->prepare( $sql );
$rs->execute() || &die_clean("Couldn't execute\n$sql\n".$Data->errstr."\n" );
($sql_update_result) = $rs->fetchrow;
$Data->disconnect();
DDL for MySQL -- if needed, just comment and I'll post one.
UPDATE (2):
Final found one complete example, though it's only for a select statement and not even inserting any VARs into the SQL: http://search.cpan.org/~timb/DBI/DBI.pm#Simple_Examples
Almost copy and paste from DBI Synopsis:
use DBI;
$dbh = DBI->connect($data_source, $username, $auth, \%attr);
$statement = "UPDATE some_table SET som_col = ? WHERE id = ?";
$rv = $dbh->do($statement, undef, $som_val, $id);
$DBI::err && die $DBI::errstr;
$rc = $dbh->disconnect;
I prefer to use do when updating or deleting since these operations doesn't return any row.
So, in order to have a little debug, i would modify your code like this:
my $sql = "UPDATE table SET column1=NULL, column2=$column2, column3=$column3 WHERE id=$id";
print STDERR "SQL: $sql\n"
my $numrows = $Data->do($sql);
if (not defined $numrows) {
print STDERR "ERROR: $DBI::errstr";
} else {
print STDERR "INFO: $numrows rows updated";
}
You can measure query response times from within your perl code, but since it is a database thing, i recommend you using any Mysql specialized tool (i don't use MySQL, sorry).
Have you considered something a bit higher level - like DBIx::Class?
You don't need to return the values, lowercase them in Perl, then update the rows. Just do that in one SQL statement:
my $sql = "UPDATE table SET column2=lower(column2) WHERE id = ?";
$sth = $dbh->prepare($sql);
foreach my $id (#ids) {
$sth->execute($id);
}
You also want to use placeholders to prevent Bobby Tables from visiting.