Agree about CHAR columns....but legacy, you know. :P btw, unifying the SQLServer and Sybase Adaptors is probably a good thing...SQLServer was actually Sybase at one point (they licensed it and then went on from there)...so most things will probably be compatible.
RTRIM shouldn't be needed because if both columns are CHAR they will match. I wrote a quick test in Sybase and confirmed that joining from a CHAR to a VARCHAR does work (without RTRIM): SQL: create table #test1 (char_data char(15) not null) create table #test2 (varchar_data varchar(15) not null) insert into #test1 values ('TEST') insert into #test2 values ('TEST') SELECT "'" + char_data + "'" as char_date_quoted from #test1 --just to show that it is padded SELECT "'" + varchar_data + "'" as varchar_date_quoted from #test2 select * from #test1 t1 join #test2 t2 on (t1.char_data = t2.varchar_data) drop table #test1 drop table #test2 Results: char_date_quoted ----------------- 'TEST ' [1 row affected] varchar_date_quoted ------------------- 'TEST' [1 row affected] char_data varchar_data --------------- ------------ TEST TEST [1 row affected] Give me a minute and I'll find a SQLServer to test on. On Thu, May 2, 2019 at 8:01 AM Andrus Adamchik <and...@objectstyle.org> wrote: > I am fairly certain RTRIM will degrade join performance on any DB, causing > the DB to bypass the index. So if we did RTRIM on the join conditions on > SQLServer, we probably shouldn't. > > Fixed-size space-padded columns (aka CHAR columns) are fundamentally > stupid and unfriendly. How are they even supposed to work? Can we join them > with VARCHARs? So many questions :) > > Andrus > > > On May 2, 2019, at 5:54 PM, Nikita Timofeev <ntimof...@objectstyle.com> > wrote: > > > > Hi, > > > > This is again about new translator. Seems like I was too optimistic > > unifying SQLServer and Sybase adapters. > > This RTRIM() behavior is from SQLServer and I wonder if it will cause > > performance issues there too. > > > > On Thu, May 2, 2019 at 3:54 AM Lon Varscsak <lon.varsc...@gmail.com> > wrote: > > > >> Hey all, > >> > >> I'm working to integrate 4.2 into my code base and I've run into a snag. > >> It appears that some queries are slower and what I'm finding is that > when I > >> have CHAR columns, that it ends up doing a join that is RTRIM(column) = > >> RTRIM(other column). This results in the query optimizer not using an > >> index (because it has to rtrim all values before comparison). > >> > >> Here is an example from a disjointed prefetch: > >> > >> 4.1.B2-SNAPSHOT: 👍 > >> > >> SELECT DISTINCT [t0].[average_cost], [t0].[backorder_flag], > >> [t0].[break_match_code], [t0].[case_location], [t0].[case_qty], > >> [t0].[category_code], [t0].[cgs_gl_account], [t0].[charges_group_code], > >> [t0].[composition_family], [t0].[composition_output_definition], > >> [t0].[custom_vendor], [t0].[description], [t0].[drop_ship_code], > >> [t0].[duties_percent], [t0].[duties_tax_cost_percent], > >> [t0].[envelope_item_number], [t0].[expect_date], [t0].[first_sale_date], > >> [t0].[freight_cost_percent], [t0].[inventory_gl_account], > [t0].[lead_time], > >> [t0].[license_required], [t0].[market], [t0].[material], > >> [t0].[merchandise_cost_percent], [t0].[operator_message], [t0].[origin], > >> [t0].[part_number], [t0].[personalization_flag], > [t0].[primary_location], > >> [t0].[print_specification], [t0].[print_template], > [t0].[procurement_code], > >> [t0].[qty_expected], [t0].[qty_on_backorder], [t0].[qty_on_hand], > >> [t0].[qty_reserved], [t0].[qty_available], [t0].[return_gl_account], > >> [t0].[sales_gl_account], [t0].[sales_unit], [t0].[serial_number_flag], > >> [t0].[special_process], [t0].[status], [t0].[tax_flag], > >> [t0].[tesla_qty_on_backorder], [t0].[tesla_qty_reserved], > >> [t0].[unit_of_measure], [t0].[vap_cost_percent], [t0].[vendor_code], > >> [t0].[weight], [t0].[root_part_number] FROM [production].[dbo].[part] > [t0] > >> JOIN [production].[dbo].[order_detail_sales] [t1] ON > *([t0].[part_number] = > >> [t1].[part_number])* JOIN [production].[dbo].[order_header] [t2] ON > >> ([t1].[order_number] = [t2].[order_number]) WHERE ([t2].[order_number] > = ?) > >> OR ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) OR > >> ([t2].[order_number] = ?) OR ([t2].[order_number] = ?) [bind: > >> 1->order_number:57874832, 2->order_number:57874792, > >> 3->order_number:57874789, 4->order_number:57874783, > >> 5->order_number:57874781, 6->order_number:57874779, > >> 7->order_number:57874777, 8->order_number:57874715, > >> 9->order_number:57874714, 10->order_number:57874713, > >> 11->order_number:57874712, 12->order_number:57874708, > >> 13->order_number:57874707, 14->order_number:57874704, > >> 15->order_number:57874657] > >> > >> 4.2.M1-SNAPSHOT: 👎 > >> > >> SELECT DISTINCT [t0].[average_cost], [t0].[backorder_flag], > >> [t0].[break_match_code], [t0].[case_location], [t0].[case_qty], > >> [t0].[category_code], [t0].[cgs_gl_account], > >> RTRIM([t0].[charges_group_code]), [t0].[composition_family], > >> [t0].[composition_output_definition], [t0].[custom_vendor], > >> [t0].[description], RTRIM([t0].[drop_ship_code]), [t0].[duties_percent], > >> [t0].[duties_tax_cost_percent], RTRIM([t0].[envelope_item_number]), > >> [t0].[expect_date], [t0].[first_sale_date], [t0].[freight_cost_percent], > >> [t0].[inventory_gl_account], [t0].[lead_time], [t0].[license_required], > >> RTRIM([t0].[market]), [t0].[material], [t0].[merchandise_cost_percent], > >> [t0].[operator_message], [t0].[origin], RTRIM([t0].[part_number]), > >> [t0].[personalization_flag], [t0].[primary_location], > >> [t0].[print_specification], [t0].[print_template], > >> RTRIM([t0].[procurement_code]), [t0].[qty_expected], > >> [t0].[qty_on_backorder], [t0].[qty_on_hand], [t0].[qty_reserved], > >> [t0].[qty_available], [t0].[return_gl_account], [t0].[sales_gl_account], > >> [t0].[sales_unit], [t0].[serial_number_flag], [t0].[special_process], > >> [t0].[status], [t0].[tax_flag], [t0].[tesla_qty_on_backorder], > >> [t0].[tesla_qty_reserved], [t0].[unit_of_measure], > [t0].[vap_cost_percent], > >> RTRIM([t0].[vendor_code]), [t0].[weight], RTRIM([t0].[root_part_number]) > >> FROM [production.dbo.part] [t0] JOIN [production.dbo.order_detail_sales] > >> [t1] ON *RTRIM([t0].[part_number]) = RTRIM([t1].[part_number])* JOIN > >> [production.dbo.order_header] [t2] ON [t1].[order_number] = > >> [t2].[order_number] WHERE ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) OR ( > >> [t2].[order_number] = ? ) OR ( [t2].[order_number] = ? ) [bind: > >> 1->order_number:57874832, 2->order_number:57874792, > >> 3->order_number:57874789, 4->order_number:57874783, > >> 5->order_number:57874781, 6->order_number:57874779, > >> 7->order_number:57874777, 8->order_number:57874715, > >> 9->order_number:57874714, 10->order_number:57874713, > >> 11->order_number:57874712, 12->order_number:57874708, > >> 13->order_number:57874707, 14->order_number:57874704, > >> 15->order_number:57874657] > >> > >> Thoughts? I also don't like that it's not writing the "ON" in > parenthesis, > >> but I'm sure that's just me be a persnickety old man. 👴 > >> > >> -Lon > >> > > > > > > -- > > Best regards, > > Nikita Timofeev > >