How to improve MYSQL full text search index with other column in the table? - full-text-search

I have this slow query (26 seconds):
SELECT uniqueIDS FROM search_V2 WHERE siteID=1 AND status=1 AND (MATCH(data) AGAINST ('scale' IN BOOLEAN MODE));
I like first the query work on siteID_status index and then work with the full search index.
Any solution for that?

So this is the best solution I found:
SELECT uniqueIDS FROM
(
SELECT * FROM search_V2 WHERE siteID=1 AND status=1
) A
WHERE MATCH(data) AGAINST ('scale' IN BOOLEAN MODE);
This post really help me: https://dba.stackexchange.com/questions/15214/why-is-like-more-than-4x-faster-than-match-against-on-a-fulltext-index-in-mysq/15218#15218?newreg=36837d8616984e289377475b27ee0758
I hope it will help someone else also.

You can tell the query which index to follow first. See Index hints at https://dev.mysql.com/doc/refman/8.0/en/index-hints.html. Without testing it your query would be something like
SELECT uniqueIDS FROM search_V2 WHERE siteID=1 AND status=1 AND (MATCH(data) AGAINST ('scale' IN BOOLEAN MODE)) USE INDEX(siteID_status,fulltext_index);
with fulltext_index being the name of your fulltext index. Hope it works, but you are close.

Related

Query with sum many columns from same table with laravel query

This seems very easy query but can't translate it into laravel query. I have table orders there are two columns total_usd and total_gbp. I want to sum each column to get total of usd and total of gbp on the page.
This query is working in phpmyadmin and I got correct result
SELECT sum(order_total_usd) as usd, sum(order_total_gbp) as gbp FROM `orders`
In laravel I've tried this
$sumOrders = Order::select('sum(order_total_gbp) as gbp, sum(order_total_usd) as usd');
when I dd($sumOrders) I've one really huge output which almost cause browser to freeze.
Where is my mistake here?
You can try something like this
$sumOrders = Order::select( \DB::raw("sum(order_total_gbp) as gbp"), \DB::raw("sum(order_total_usd) as usd"))->get();
You can use selectRaw
$sumOrders = Order::selectRaw('sum(order_total_gbp) as gbp, sum(order_total_usd) as usd');
Except for one missed word, your code is OK. Add "Raw" after "select" as shown:
$sumOrders =
Order::selectRaw(
'sum(order_total_gbp) as gbp,
sum(order_total_usd) as usd'
);
Just replace "Order::select(...)" with Order::selectRaw(...).
Have a great day!

yii2 active record query

I need to make query (in search model) where:
Get current row index (not id)
Do a manipulation with that count (multiply this on constant number) and add if condition (if 'row index' > 10)
See this count in the model
Some steps I resolve:
I know how to create 'new column' and see it in the gridview:
$query->select([
'{{tour}}.*',
'(1000 / 'need to add row index' ) as points' //$points
]);
I know how to get a current index, but with active record:
MyModel::find()->andFilterWhere(['>=', 'cumulative_points', $playerPoints])->count();
But I need to combine this query. Anybody can help me?
Thanks.
When you need you can express the content of SQL part like literal and then assign the select content you prefer (not using array / hash assignment) this way
$query->select(' tour.*, 1000 / id ) as points' )
Sostantially you can assign to activeQuery select() method exactly the select part of you query ..
http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html

OFFSET/LIMIT only count DISTINCT values in Activerecord query

I am running this query
Playlistship.order("created_at desc").select("distinct playlist_id").limit(12).offset(2)
This query does not necessarily return 12 records. It returns the number of distinct records in the set of 12 defined by the LIMIT, OFFSET and ORDER parameters.
For example if the Playlistships between id=13 and id=24 had playlist_ids of [2,3,3,5,6,3,5,6,8,11,12,12], then this query will only give return 7 records, corresponding to the first ones having the playlist_ids [2,3,5,6,8,11,12].
What I would like to find is a query that yields 12, records with distinct playlist_ids, with the correct offset so that running this query again with an OFFSET of 3 would yield the next 12 records with distinct playlist_ids.
Hopefully I didn't "over explain" this one, as I think it's a relatively straightforward question. Please ask for more details if you need them.
Thanks!
Have you tried with subqueries? Give this a try:
Playlistship.select("distinct playlist_id").limit(12).where(playlist_id: Playlistship.order("created_at desc").select('playlist_id').offset(2))

Conditional Query or Model in Cognos Reporting

I'm new to Cognos Reporting and I'm wondering there is a way to create models/queries that are conditional. For example:
"if x is not null then append this 'where line' to query"
Something like that, I'm still pretty new to Cognos so I may be using the wrong words.
Please help me out.
Thanks.
If you want to filter rows of a query subject,
Right click your query subject> Edit Defition> Filters Tab > Add a filter
In the expression definition box,
x is null or (x is not null and <where expression to append>)
If you want to apply the filter for a query item
case
when x is not null and <where expression to append>
then <some_query_item>
else <some_query_item>
end

set filter to - INLIST - Visual Foxpro 7

I am working on some legacy code, and I have the following wonderful issue. I am hoping some FoxPro experts can help!
The infrastructure of this legacy system is setup so that I have to use the built-in expression engine to return a result set, so no go on the SQL (i know that would be so much easier!)
Here is the issue.
I need to be able to do something like
PUBLIC ARRAY(20) ArrayOfValuesToFilterBy
SELECT dataTable
SET FILTER TO logicalField = .T. and otherField NOT INLIST(ArrayOfValuesToFilterBy)
However, I know this wont work, I just need the equivalency...not using SQL.
I can generate the list of values to filter by via SQL, just not the final record select due to the legacy infrastructure constraint.
Thanks!
First, a logical field you do not have to do explicit
set filter to Logicalfield = .t.
you can just do
set filter to LogicalField
or
set filter to NOT LogicalField
Next, on the array. VFP has a function ASCAN() which will scan an array for a value, if found, will return the row number within the array that matches what you are looking for.
As for arrays... ex:
DIMENSION MyArray[3]
MyArray[1] = "test1"
MyArray[2] = "something"
MyArray[3] = "anything else"
? ASCAN( MyArray, "else" ) && this will return 0
? ASCAN( MyArray, "anything else" ) && this will return 3
If you are doing a "set filter", the array needs to be "in scope" for the duration of the filter. If you set filter in a procedure the array exists, leave the procedure and the array is gone, you're done.
So, you could do
set filter to LogicalField and ASCAN( YourArray, StringColumnFromTable ) > 0
Now, if you want a subset to WORK WITH, you can do a SQL-Select and pull the data into a CURSOR (temporary read-write table) that has the same capabilities of the original table (except auto-increment when adding)...
I typically name my temporary cursors prefixed with "C_" for "CURSOR OF" so when I'm working with tables, I know if its production data, or just available for temp purposes for quicker display, presentation, extractions from other origins as needed.
use in select( "C_FinalRecords" )
select * from YourTable ;
where LogicalField ;
and ASCAN( YourArray, StringColumnFromTable ) > 0;
into cursor C_FinalRecords READWRITE
Then, you can just use that...
select C_FinalRecords
scan
do something with the record, or values of it...
endscan
or.. bind to a grid in a form, etc...
The INLIST() function takes an expression to search for and up to 24 expressions of the same data type to search.
SELECT dataTable
SET FILTER TO logicalField = .T. AND NOT INLIST(otherField, 'Value1', 'Value2', 'Value3', 'Value4')
I am making some assumptions here, that what you want to do is create a filter with a dynamic in list statement ? If this is correct have a play with this example :-
lcList1="ABCD"
lcList2="EFGH"
lcList3="IJKL"
lcList4="MNOP"
lcList5="QRST"
lcFullList=""
lcFullList=lcFullList+"'"+lcList1+"',"
lcFullList=lcFullList+"'"+lcList2+"',"
lcFullList=lcFullList+"'"+lcList3+"',"
lcFullList=lcFullList+"'"+lcList4+"',"
lcFullList=lcFullList+"'"+lcList5+"'"
lcField="PCode"
lcFilter="SET FILTER TO INLIST ("+lcField+","+lcFullList+")"
The results of the above would create the following filter statement and store it in lcFilter
SET FILTER TO INLIST (PCode,'ABCD','EFGH','IJKL','MNOP','QRST')
you can then use macro substitution
Select dataTable
&lcFilter
Bear in mind that there is likely to be some limitations on how many items you can define in a INLIST() statement

Resources