Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support explain plan for the TDS adapter #273

Merged
merged 4 commits into from
Oct 4, 2020

Conversation

leandrocp
Copy link
Contributor

@leandrocp leandrocp commented Sep 26, 2020

That's still a draft but it's working so you can test it locally. I'm not a SQL Server expert but looks like the result set has all the information we would need for a v1 (like the screenshot on the link below), so no need to parse XML.

I believe it's good enough for review, see #273 (comment).

Also see #231 (comment) for reference.

Wdyt?

params = prepare_params(params)

case Tds.query_multi(conn, build_explain_query(query), params, opts) do
{:ok, [_, %Tds.Result{} = result, _]} ->
Copy link
Contributor Author

@leandrocp leandrocp Sep 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if the order is deterministic, but looks like it's (still need to confirm on TDS code).

/edit After digging and testing, looks like that's safe.

|> IO.iodata_to_binary()
end

defp format_result_as_table(columns, rows) do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those function are exactly the same as used on myxql adapter, should I move those to Ecto.Adapters.SQL and put a @doc false?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can introduce a function called format_table in there and make it generally available. :)

@josevalim
Copy link
Member

Looks great, awesome job! ❤️

@leandrocp
Copy link
Contributor Author

leandrocp commented Oct 4, 2020

@josevalim that's how a TDS explain looks like:

+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+--------+--------+----------------------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-----------------------+-----------------------+------------+-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+----------+----------+--------------------+
| Rows | Executes | StmtText                                                                                                                                                                                                                                                                                                                   | StmtId | NodeId | Parent | PhysicalOp           | LogicalOp            | Argument                                                                                                                           | DefinedValues                                                                                                                                                                                                                                                                            | EstimateRows | EstimateIO            | EstimateCPU           | AvgRowSize | TotalSubtreeCost      | OutputList                                                                                                                                                                                                                                                                               | Warnings | Type     | Parallel | EstimateExecutions |
+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+--------+--------+----------------------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-----------------------+-----------------------+------------+-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+----------+----------+--------------------+
|    0 |        1 | SELECT TOP(1) p0.[id], p0.[counter], p0.[title], p0.[blob], p0.[public], p0.[cost], p0.[visits], p0.[wrapped_visits], p0.[intensity], p0.[bid], p0.[uuid], p0.[meta], p0.[links], p0.[intensities], p0.[posted], p0.[author_id], p0.[inserted_at], p0.[updated_at] FROM [posts] AS p0 WHERE (p0.[title] = N'explain_test') |      1 |      1 |      0 | NULL                 | NULL                 | NULL                                                                                                                               | NULL                                                                                                                                                                                                                                                                                     |          1.0 | NULL                  | NULL                  | NULL       |  0.003283380065113306 | NULL                                                                                                                                                                                                                                                                                     | NULL     | SELECT   | false    | NULL               |
|    0 |        1 |   |--Top(TOP EXPRESSION:((1)))                                                                                                                                                                                                                                                                                             |      1 |      2 |      1 | Top                  | Top                  | TOP EXPRESSION:((1))                                                                                                               | NULL                                                                                                                                                                                                                                                                                     |          1.0 |                   0.0 | 1.0000000116860974e-7 |      16306 |  0.003283380065113306 | [p0].[id], [p0].[title], [p0].[counter], [p0].[blob], [p0].[bid], [p0].[uuid], [p0].[meta], [p0].[links], [p0].[intensities], [p0].[public], [p0].[cost], [p0].[visits], [p0].[wrapped_visits], [p0].[intensity], [p0].[author_id], [p0].[posted], [p0].[inserted_at], [p0].[updated_at] | NULL     | PLAN_ROW | false    |                1.0 |
|    0 |        1 |        |--Clustered Index Scan(OBJECT:([ecto_test].[dbo].[posts].[posts_pkey] AS [p0]), WHERE:([ecto_test].[dbo].[posts].[title] as [p0].[title]=N'explain_test'))                                                                                                                                                         |      1 |      3 |      2 | Clustered Index Scan | Clustered Index Scan | OBJECT:([ecto_test].[dbo].[posts].[posts_pkey] AS [p0]), WHERE:([ecto_test].[dbo].[posts].[title] as [p0].[title]=N'explain_test') | [p0].[id], [p0].[title], [p0].[counter], [p0].[blob], [p0].[bid], [p0].[uuid], [p0].[meta], [p0].[links], [p0].[intensities], [p0].[public], [p0].[cost], [p0].[visits], [p0].[wrapped_visits], [p0].[intensity], [p0].[author_id], [p0].[posted], [p0].[inserted_at], [p0].[updated_at] |          1.0 | 0.0031250000465661287 | 1.5809999604243785e-4 |      16306 | 0.0032830999698489904 | [p0].[id], [p0].[title], [p0].[counter], [p0].[blob], [p0].[bid], [p0].[uuid], [p0].[meta], [p0].[links], [p0].[intensities], [p0].[public], [p0].[cost], [p0].[visits], [p0].[wrapped_visits], [p0].[intensity], [p0].[author_id], [p0].[posted], [p0].[inserted_at], [p0].[updated_at] | NULL     | PLAN_ROW | false    |                1.0 |
+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+--------+--------+----------------------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-----------------------+-----------------------+------------+-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+----------+----------+--------------------+

That will look ugly when printed to a console that wraps the lines, but you can copy&paste to an editor, save to a file, or configure the console if that's possible. Anyway, I suppose that's good enough for the first version. Wdyt?

@leandrocp leandrocp marked this pull request as ready for review October 4, 2020 15:14
@josevalim josevalim merged commit 0798542 into elixir-ecto:master Oct 4, 2020
@josevalim
Copy link
Member

Awesome job! ❤️

@leandrocp leandrocp deleted the tds-explain branch October 4, 2020 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants