How to search numeric by Sphinx correctly? - sphinx

I need make search on billion records in MySQL and it's very long process (it's works now). May be Sphinx help me? How correctly to configure Sphinx for search numbers? Should I use integer attribute for searching (not string field)?
I need to get only row where the timestamp 'nearest or equal' to query:
CREATE TABLE test ( date TIMESTAMP(6) UNIQUE, num INT(32) );
| 2018-07-02 05:50:33.084011 | 282 |
| 2018-07-02 05:50:33.084028 | 475 |
...
(40 M such rows... all timestamps is unique, so this column are unique index so I no need in create additional index I suppose.)
sphinx.conf:
source src1
{
type = mysql
...
sql_query = SELECT * FROM test
}
indexer...
Sphinx 3.0.3
...
indexing index 'test'...
collected 40000000 docs, 0.0 MB
In my test I find nearest timestamp to query:
$start = microtime(true);
$query = '2018-07-02 05:50:33.084011';
$connMySQL = new PDO('mysql:host=localhost;dbname=test','','');
$sql = "SELECT * FROM test WHERE date <= '$search' ORDER BY date DESC LIMIT 1";
$que = $connMySQL->query($sql);
$result = $que->fetchAll(PDO::FETCH_ASSOC);
$query = $connMySQL->query('reset query cache');
$connMySQL = null;
print_r ($result);
echo 'Time MySQL:'.(microtime(true) - $start).' sec.';
$start = microtime(true);
$query = '2018-07-02 05:50:33.084029';
$connSphinxQL = new PDO('mysql:host=localhost;port=9306;dbname=test','root','');
$sql = "SELECT * FROM test WHERE date <= '$search' ORDER BY date DESC LIMIT 1";
$que = $connSphinxQL->query($sql);
$result = $que->fetchAll(PDO::FETCH_ASSOC);
$query = $connSphinxQL->query('reset query cache');
$connSphinxQL = null;
print_r ($result);
echo 'Time Sphinx:'.(microtime(true) - $start).' sec.';
Output:
[date] => 2018-07-02 05:50:33.084011 [num] => 282 Time MySQL: 0.00193 sec.
[date] => 2018-07-02 05:50:33.084028 [num] => 475 Time Sphinx: 0.00184 sec.
I suggested to see some different resuts, but noticed that before indexing I have got the same result, so I think Sphinx searches directy in MySQL by the reason of my wrong configuration.
Only ask here I found: no text search

Should I use integer attribute for searching (not string field)?
Yes. But an added complication, is a index NEEDS at least one field (sphinx isnt really designed as a general database, its intended for text queries!)
Can synthesize a fake one.
sql_query = SELECT unix_timestamp(`date`) AS id, 'a' AS field, num FROM test
sql_attr_uint = num
Also shows that need a unique integer as the first column, to be a document_id, seems as your timestamp is unique, can use that. a UNIX_TIMESTAMP is a nice easy way to represent a timestamp as a plain integer.
Can use id in queries too, for filtering, so would need to convert to a timestamp at the same time.
$query = '2018-07-02 05:50:33.084011';
$id = strtotime($query)
$sql = "SELECT * FROM test WHERE id <= '$id' ORDER BY id DESC LIMIT 1";

Related

Column is not updating in postgresql

I tried to update my table like below:
$query = "select *
FROM sites s, companies c, tests t
WHERE t.test_siteid = s.site_id
AND c.company_id = s.site_companyid
AND t.test_typeid = '20' AND s.site_id = '1337'";
$queryrow = $db->query($query);
$results = $queryrow->as_array();
foreach($results as $key=>$val){
$update = "update tests set test_typeid = ? , test_testtype = ? where test_siteid = ?";
$queryrow = $db->query($update,array('10','Meter Calibration Semi Annual',$val->site_id));
}
The above code is working good. But in update query , The column test_typeid is not updated with '10'. Column test_typeid is updating with empty value. Other columns are updating good. I dont know why this column test_typeid is not updating? And the column test_typeid type is integer only. I am using postgreSql
And My table definition is:
What i did wrong with the code. Kindly advice me on this.
Thanks in advance.
First, learn to use proper JOIN syntax. Never use commas in the FROM clause; always use proper explicit JOIN syntax.
You can write the query in one statement:
update tests t
set test_typeid = '10',
test_testtype = 'Meter Calibration Semi Annual'
from sites s join
companies c
on c.company_id = s.site_companyid
where t.test_siteid = s.site_id and
t.test_typeid = 20 and s.site_id = 1337;
I assume the ids are numbers, so there is no need to use single quotes for the comparisons.

how to get specific rows page number in pagination

I have a question on MySQL paging. A user's record is displayed on a table with many other user's record. and the table is sorted/paged. Now I need to display the page that containing the user's row directly after the user login. How can I achieve this?
create table t_users (id int auto_increment primary key, username varchar(100)); insert t_users(username) values ('jim'),('bob'),('john'),('tim'),('tom'), ('mary'),('elise'),('karl'),('karla'),('bob'), ('jack'),('jacky'),('jon'),('tobias'),('peter');
I searched the google but not found answer so please help
There are two steps for this:
1. Determine the row's position in your sorted table.
Copied and tweaked from: https://stackoverflow.com/a/7057822/2391142
Use this SQL...
SELECT z.rank FROM (
SELECT id, #rownum := #rownum + 1 AS rank
FROM t_users, (SELECT #rownum := 0) r
ORDER BY id ASC
) as z WHERE id=1;
...replacing the ORDER BY id ASC with whatever your actual sort order is. And replacing the number 1 in WHERE id=1 with the provided number in that index.php?u=id url.
2. Determine the page number based on the row's position.
Use this PHP to determine the needed page number...
$rows_per_page = 50;
$user_row_position = [result you got from step 1];
$page = ceil($user_row_position / $rows_per_page);
...replacing the 50 with whatever your real rows-per-page limit is, and putting the real SQL result in $users_row_position.
And voila. You'll have the destination page number in the $page variable and hopefully you can take it from there.
EDIT
After further discussion in the comments, use this bit of PHP:
$page = 0;
$limit = 10;
// If a user ID is specified, then lookup the page number it's on.
if (isset($_GET['u'])) {
// Check the given ID is valid to avoid SQL injection risks.
if (is_numeric($_GET['u'])) {
// Lookup the user's position in the list.
$query = mysqli_fetch_array(mysqli_query($link, "SELECT z.rank FROM (SELECT id, #rownum := #rownum + 1 AS rank FROM sites, (SELECT #rownum := 0) r WHERE online='0') as z WHERE id=" . $_GET['u']));
$position = $query[0];
if (is_numeric($position)) {
// Convert the result to a number before doing math on it.
$position = (int) $position;
$page = ceil($position / $limit);
}
}
}
// If a page number is specified, and wasn't already set by looking a user, then lookup the real starting row.
if ($page == 0 && isset($_GET['page'])) {
// Check your given page number is valid too.
if (is_numeric($_GET['page'])) {
$page = (int) $_GET['page'];
}
}
// Notice that if anything fails in the above checks, we just pretend it never
// happened and keep using the default page and start number of 0.
// Determine the starting row based off the page number.
$start = ($page - 1) * $limit;
// Get the list of sites for the provided page only.
$query = mysqli_query($link, "SELECT * FROM sites WHERE online='0' LIMIT " . $start . ", " + $limit);
while ($row = mysqli_fetch_array($query)) {
// Stuff to render your rows goes here.
// You can use $row['fieldname'] to extract fields for this row.
}

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")

mysqli - fetch several rows applying several where conditions

With only one query I want to fetch specific rows that contains a range of several string values. Is it possible to modify my WHERE to do this?
This is the code for one country but I want to select several rows for several countries. For example: Jamaica, Portugal and Dominica.
// Select countries to show
$specific_country = Dominica;
// Select and write SPECIFIC ROWS data
$result = mysqli_query($con, "SELECT * FROM $table WHERE Country='$specific_country'");
This will only get the rows of Dominica but I wanted to use something similar to get Jamaica, Portugal and Dominica but all on the same query.
You can use IN()
SELECT *
FROM table_name
WHERE Country IN('Jamaica', 'Portugal', 'Dominica')
Here is SQLFiddle demo
In php
$countries = array('Jamaica', 'Portugal', 'Dominica');
$sql = "SELECT * FROM table_name WHERE Country IN('". implode("','", $countries) . "')";
$result = mysqli_query($con, $sql);
...

how to convert count(*) and group by queries to yii and fetch data from it

I want to convert this query in yii
SELECT count(*) AS cnt, date(dt) FROM tbl_log where status=2 GROUP BY date(dt)
and fetch data from that. I try this command (dt is datetime field):
$criteria = new CDbCriteria();
$criteria->select = 'count(*) as cnt, date(dt)';
$criteria->group = 'date(dt)';
$criteria->condition = 'status= 2';
$visit_per_day = $this->findAll($criteria);
but no data will fetch!
wath can I do to get data?
Probably you see no data because you need assign data to model attributes which doesn't exist.
$criteria = new CDbCriteria();
$criteria->select = 'count(*) AS cnt, date(dt) AS dateVar';
$criteria->group = 'date(dt)';
$criteria->condition = 'status= 2';
$visit_per_day = $this->findAll($criteria);
This means that your model must have attributes cnt and dateVar in order to show your data. If you need custom query then check Hearaman's answer.
Try this below code
$logs = Yii::app()->db->createCommand()
->select('COUNT(*) as cnt')
->from('tbl_log') //Your Table name
->group('date')
->where('status=2') // Write your where condition here
->queryAll(); //Will get the all selected rows from table
Number of visitor are:
echo count($logs);
Apart from using cDbCriteria, to do the same check this link http://www.yiiframework.com/forum/index.php/topic/10662-count-on-a-findall-query/
If you use Yii2 and have a model based on table tbl_log, you can do it in model style like that:
$status = 2;
$result = Model::find()
->select('count(*) as cnt, date(dt)')
->groupBy('date(dt)')
->where('status = :status')
->params([':status' => $status ])
->all();