MariaDB ODBC Connector performance issue - mariadb

We try to switch from MySQL 5.0.96 to MariaDB 10.5.9. Move data to MariaDB server was easy but problem is with speed of MariaDB ODBC connector. I tried 3.1.12 with default settings without SSL and our applications (mostly written in Embarcadero RAD Studio) showed very poor performance. When I tried MySQL ODBC connector 8.0.24 everything ran smoothly. Queries through MariaDB's connector was 3-5 times slower. In general query log I found that MariaDB's connector generates a lot of queries to information_scheme.columns table and repeatedly it reads variable TX_ISOLATION.
Short extract from general query log - MariaDB connector:
3 Query SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='TX_ISOLATION'
3 Prepare select * from stanice
3 Execute select * from stanice
3 Prepare SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION KEY_SEQ, 'PRIMARY' PK_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'pri' AND TABLE_SCHEMA LIKE 'unicentrum' AND TABLE_NAME LIKE 'stanice' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
3 Execute SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION KEY_SEQ, 'PRIMARY' PK_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'pri' AND TABLE_SCHEMA LIKE 'unicentrum' AND TABLE_NAME LIKE 'stanice' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
3 Close stmt
3 Reset stmt
3 Query SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='TX_ISOLATION'
3 Prepare SELECT * FROM stanice WHERE Sit_ID = ? ORDER BY Sit_ID, Podsit_ID, ID
3 Execute SELECT * FROM stanice WHERE Sit_ID = 1 ORDER BY Sit_ID, Podsit_ID, ID
3 Prepare SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION KEY_SEQ, 'PRIMARY' PK_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'pri' AND TABLE_SCHEMA LIKE 'unicentrum' AND TABLE_NAME LIKE 'stanice' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
3 Execute SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION KEY_SEQ, 'PRIMARY' PK_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'pri' AND TABLE_SCHEMA LIKE 'unicentrum' AND TABLE_NAME LIKE 'stanice' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
3 Close stmt
3 Reset stmt
MySQL connector:
3 Query SELECT ##tx_isolation
...
3 Query select * from stanice
3 Prepare SELECT * FROM stanice WHERE Sit_ID = ? ORDER BY Sit_ID, Podsit_ID, ID
3 Execute SELECT * FROM stanice WHERE Sit_ID = '1' ORDER BY Sit_ID, Podsit_ID, ID
3 Close stmt
I think those "unnecessary" queries are making difference in performance of those connectors. Any ideas what could I do to speed up MariaDB's connector? Thanks

I've opened https://jira.mariadb.org/browse/ODBC-313 for the problem you've described. It would be better to continue there, as at least ODBC trace of the run with both drivers is required to address main issue.

Related

In teradata, can you insert a cte into a table?

I've looked at the other postings but I haven't seen a resolution for this.
CREATE TABLE newtable AS (SELECT * FROM yourtable) with no data ;
Then
with cte as (
select top 10* from yourtable
)
insert into newtable
select * from cte
select * from newtable
I get an error saying it expects a select and not an insert.
How would I accomplish inserting the cte into a table?

Querying 11g Oracle database from SQL Server 2012

I have an Oracle database in one server and SQL Server database in another server. I did a count query on the Oracle database locally which returns certain amount of records. However, I was given different record count when I do the same query from the SQL Server.
Below is the Oracle query statement;
select count(*) as TOTALDATA
from
(
select b.name,b.prprty,b.result
from thedatabase.ip_smpl a, thedatabase.ip_tst_rslt b
where a.name = b.name
and a.smpl_dt_tm < to_date(to_char(sysdate,'dd/mm/yyyy')||' 00:00','dd/mm/yyyy hh24:mi')
and a.smpl_dt_tm > to_date(to_char(sysdate-30,'dd/mm/yyyy')||' 00:00','dd/mm/yyyy hh24:mi')
and b.result is not null
and b.name not like 'T%')
Meanwhile, here is the equivalent SQL Server query statement;
SELECT COUNT(*) AS TOTALDATA
FROM
(
SELECT b.NAME, b.PRPRTY, b.RESULT
FROM [LinkedServer]..[thedatabase].[IP_SMPL] a, [LinkedServer]..[thedatabase].[IP_TST_RSLT] b
WHERE a.NAME = b.NAME
AND a.SMPL_DT_TM < CAST(CONVERT(varchar, GETDATE(), 23) + ' 00:00' AS DATETIME)
AND a.SMPL_DT_TM > CAST(CONVERT(varchar, GETDATE() - 30, 23) + ' 00:00' AS DATETIME)
AND b.RESULT IS NOT NULL
AND b.NAME NOT LIKE 'T%') AS D
The former query returns 18263 rows of record while the latter 17849.
Why the different? Perhaps the SQL statement is not literally translated to the same as Oracle statement?
Note that I get same record count if I ran each query minus two last statements.

bulk update in SQLite

I have 2 tables with identical structure I want to update one table using data from the other, matching on primary key. SQLite has a with (CTE) statement but the following doesn't work (sqlite3 v. 3.29.0):
sqlite> select * from main;
1|A
2|B
4|D
5|E
6|F
sqlite> select * from temp;
1|aa
2|bb
3|cc
4|dd
5|ee
sqlite> with mapping as (select main.ID, temp.Desc from main join temp on temp.ID=main.ID) update main set Desc=mapping.Desc where main.ID=mapping.ID;
Error: no such column: mapping.Desc
I've tried using "select main.ID as ID, temp.Desc as Desc", but get the same error message.
To update your main table from your cte, use a subquery, since sqlite doesn't support update from
with mapping as
(select main.ID, temp.Desc
from main
join temp on temp.ID=main.ID)
update main set Desc=
(select Desc from mapping where ID = main.ID limit 1);
see dbfiddle

How can drop table if table exists in oracle?

I am trying to create database by my java application using my generated schema file. In schema I have included drop query also. But I want to do some improvements for DROP QUERY. So I want to check the existence of db objects before running drop query and drop only when if it exists.
I googled for it and found some oracle link, Some link suggest following syntax and some mentioned that ORACLE does not support such syntax.
SYNTAX A:
IF EXISTS DROP TABLE TABLE_NAME
SYNTAX B:
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
I also tried following queries:-
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' )
DROP TABLE [BBB]
but it was giving error:-
Error starting at line 2 in command:
DROP TABLE [BBB]
Go
Error report:
SQL Error: ORA-00903: invalid table name
00903. 00000 - "invalid table name"
*Cause:
*Action:
Error starting at line 1 in command:
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' ) DROP TABLE [BBB]
Error report:
Unknown Command
I refered following links:-
https://community.oracle.com/thread/2421779?tstart=0
Please suggest me if there any other queries to drop table with condition if table exists.
Drop table with no check. If any error exists you'll never know when something went wrong.
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
Or you can search in Oracle dictionary.
DECLARE
l_cnt NUMBER;
BEGIN
SELECT count(*)
INTO l_cnt
FROM user_tables
WHERE table_name = 'MY_TABLE';
IF l_cnt = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
END IF;
END;
If you run following code you do not have to check if table exists and in case of errors (table is locked with now wait or any other you will know about it)
begin
for c1 in (select owner,table_name from dba_tables where table_name='MY_TABLE') loop
execute immediate 'drop table '||c1.owner||'.'||c1.table_name||'';
end loop;
end;
Try this : It will drop table 'table_name' if it is present .
declare
a varchar2(700) ;
begin
execute immediate ' SELECT CASE WHEN tab = 1
THEN ''DROP TABLE TABLE_NAME''
ELSE ''select 1 from dual''
END
FROM ( SELECT sum(case when table_name = ''TABLE_NAME'' then 1 else 0 end ) as tab FROM user_tables)' into a;
EXECUTE IMMEDIATE a;
end;

How can I see the last SQL statement executed in Oracle database 11g r2?

I am new to oracle database.
Can someone give me an example of the steps for how to see the last statements executed on the Oracle database 11g r2?
You can use the below query to get the last sql executed based on last sql which was active in database
select ltrim(sq.sql_text)
from v$sql sq, v$session se, v$open_cursor oc
where sq.sql_id = oc.sql_id
and se.saddr = oc.saddr
and se.sid = oc.sid
and se.audsid = SYS_CONTEXT('userenv', 'sessionid')
order by oc.LAST_SQL_ACTIVE_TIME desc;
You can also use the below to find the last query executed in your session.
SELECT (SELECT t2.sql_fulltext
FROM v$sql t2
WHERE t1.prev_sql_id = t2.sql_id
AND t1.prev_child_number = t2.child_number) sql_fulltext
FROM v$session t1
WHERE t1.audsid = Sys_context('userenv', 'sessionid');
You can use the below query:
SELECT program_id, program_line#, sql_text
FROM V$SQL VS , ALL_USERS AU
WHERE (executions >= 1)
AND (parsing_user_id != 0)
AND (AU.user_id(+) = VS.parsing_user_id)
AND UPPER(AU.USERNAME) IN (UPPER('YourUser'))
ORDER BY last_active_time DESC;
if you need to know the statements of an PL/SQL object were executed then use or join with
select *
from dba_objects
where object_id = program_id
Find all sql where sql is like ....
select h.sample_time
, u.username
, h.machine
, s.sql_text
, h.*
from dba_hist_active_sess_history h
inner join v$sql s
on s.sql_id = h.sql_id
left outer join dba_users u
on u.user_id = h.user_id
where s.sql_text like 'DELETE%'
order by h.sample_time desc;
You need to be connected as sysdba user for this sql
A couple of hints:
In SQLplus, type a semicolon+ to see, and slash to execute again
In SQLdeveloper, use F8
If you mean see other users' statements then it's not possible by default.
You can configure AUDIT.
You can see some SQL statements in SELECT * FROM V$SQLAREA;
Connect as SYS user and execute the following query
select sql_text from v$sql where first_load_time=(select max(first_load_time) from v$sql) ;
select sq.PARSING_SCHEMA_NAME, sq.LAST_LOAD_TIME, sq.ELAPSED_TIME, sq.ROWS_PROCESSED, ltrim(sq.sql_text)
from v$sql sq, v$session se
where sq.PARSING_SCHEMA_NAME = 'YOUR_SCHEMA'
order by sq.LAST_LOAD_TIME desc;

Resources