Hi, devs,

I have started the vote[1] for this FLIP. If you have any questions, please
don't hesitate to reply to this thread.

[1] https://lists.apache.org/thread/bsgqvvs9wx1dkv7p3m9ctockh84rl11j

Best,
Jane

On Fri, Jan 6, 2023 at 6:48 PM Jane Chan <qingyue....@gmail.com> wrote:

> Hi, devs,
>
> Thanks for all the feedback.
>
> Based on the discussion[1], we seem to have a consensus so far, so I would
> like to start a vote on FLIP-280[2], which begins on the following Monday
> (Jan 9th at 10:00 AM GMT).
>
> If you have any questions or doubts, please do not hesitate to follow up
> on this discussion.
>
> Best,
> Jane
>
> [1] https://lists.apache.org/thread/5xywxv7g43byoh0jbx1b6qo6gx6wjkcz
> [2]
> https://cwiki.apache.org/confluence/display/FLINK/FLIP-280%3A+Introduce+EXPLAIN+PLAN_ADVICE+to+provide+SQL+advice
>
> On Fri, Jan 6, 2023 at 4:27 PM Jingsong Li <jingsongl...@gmail.com> wrote:
>
>> Thanks Jane for your feedback.
>>
>> `EXPLAIN PLAN_ADVICE` looks good to me.
>>
>> Best,
>> Jingsong
>>
>> On Thu, Jan 5, 2023 at 5:20 PM Jane Chan <qingyue....@gmail.com> wrote:
>> >
>> > Hi, devs,
>> >
>> > After discussing with Godfrey <godfre...@gmail.com>, Lincoln
>> > <lincoln.8...@gmail.com>, and Jark <imj...@gmail.com>, I've updated the
>> > FLIP document[1] and look forward to your opinions and suggestions.
>> >
>> > The highlight difference is listed as follows.
>> >
>> >    - *The proposed syntax changes from EXPLAIN ANALYZED_PHYSICAL_PLAN
>> >    <query> to EXPLAIN PLAN_ADVICE <query>*.
>> >       - The reason for changing the syntax is that the output format and
>> >       analyzed target are two orthogonal concepts and better be
>> > decoupled. On the
>> >       other hand, users may care about the advice content instead of
>> which plan
>> >       is analyzed, and thus PHYSICAL should be kept from users.
>> >
>> >
>> >    - *The output format changes from JSON to current tree-style text.
>> >    Introduce ExplainFormat to classify the output format.*
>> >       - The current output format is a mixture of plain text (AST,
>> >       Optimized Physical Plan, and Optimized Execution Plan) and JSON
>> (Physical
>> >       Execution Plan,  via EXPLAIN JSON_EXECUTION_PLAN ), which is not
>> > structured
>> >       and categorized. By introducing ExplainFormat, we can better
>> classify the
>> >       output format and have more flexibility to extend more formats in
>> the
>> >       future.
>> >
>> >
>> >    - *The PlanAnalyzer installation gets rid of SPI.*
>> >       - PlanAnalyzer should be an internal interface and not be exposed
>> to
>> >       users. Therefore, the Factory mechanism is unsuitable for this.
>> >
>> >
>> > To Godfrey <godfre...@gmail.com>, Jingsong <jingsongl...@gmail.com>,
>> and
>> > Shengkai <fskm...@gmail.com>, Thanks for your comments and questions.
>> >
>> > @Jingsong
>> >
>> > > Can you give examples of other systems for the syntax?
>> > > In other systems, is EXPLAIN ANALYZE already PHYSICAL_PLAN?
>> > >
>> >
>> > For other systems like MySQL[2], PostgreSQL[3], Presto[4], and TiDB[5]
>> >
>> > EXPLAIN ANALYZE <query>
>> > is the mainstream syntax.
>> >
>> > However, it represents an actual measurement of the cost, i.e., the
>> > statement will execute the statement, which is unsuitable for this
>> > condition.
>> >
>> >
>> > `EXPLAIN ANALYZED_PHYSICAL_PLAN <query>` looks a bit strange, and even
>> > > stranger that it contains `advice`. The purpose of FLIP seems to be a
>> bit
>> > > more to `advice`, so can we just
>> > > introduce a syntax for `advice`?
>> >
>> >
>> > Good point. After several discussions, the syntax has been updated to
>> >
>> > EXPLAIN PLAN_ADVICE <query>
>> >
>> > @Godfrey
>> >
>> > Do we really need to expose `PlanAnalyzerFactory` as public interface?
>> > > I prefer we only expose ExplainDetail#ANALYZED_PHYSICAL_PLAN and the
>> > > analyzed result.
>> > > Which is enough for users and consistent with the results of `explain`
>> > > method.The classes about plan analyzer are in table planner module,
>> which
>> > > does not public api (public interfaces should be defined in
>> > > flink-table-api-java module). And PlanAnalyzer is depend on RelNode,
>> which
>> > > is internal class of planner, and not expose to users.
>> >
>> >
>> > Good point. After reconsideration, the SPI mechanism is removed from the
>> > FLIP. PlanAnalyzer should be an internal implementation much similar to
>> a
>> > RelOptRule, and should not be exposed to users.
>> >
>> > @Shengkai
>> >
>> > > 1. `PlanAnalyzer#analyze` uses the FlinkRelNode as the input. Could
>> you
>> > > share some thoughts about the motivation? In my experience, users
>> mainly
>> > > care about 2 things when they develop their job:
>> >
>> > a. Why their SQL can not work? For example, their streaming SQL
>> contains an
>> > > OVER window but their ORDER key is not ROWTIME. In this case, we may
>> don't
>> > > have a physical node or logical node because, during the
>> optimization, the
>> > > planner has already thrown the exception.
>> > >
>> >
>> >  The prerequisite for providing advice is that the optimized physical
>> can
>> > be generated. The planner should throw exceptions if the query contains
>> > syntax errors or other problems.
>> >
>> >
>> >
>> > > b. Many users care about whether their state is compatible after
>> upgrading
>> > > their Flink version. In this case, I think the old execplan and the
>> SQL
>> > > statement are the user's input.
>> >
>> >
>> > Good point. State compatibility detection is beneficial, but it better
>> be
>> > decoupled with EXPLAIN PLAN_ADVICE. We could provide a separate
>> mechanism
>> > for cross-version validation.
>> >
>> >
>> > 2. I am just curious how other people add the rules to the Advisor. When
>> > > rules increases, all these rules should be added to the Flink
>> codebase?
>> >
>> >
>> > It is much similar to adding a RelOptRule to RuleSet. The number of
>> > analyzers will not be growing too fast. So adding them to the Flink
>> > codebase may not be a concern.
>> >
>> >
>> > 3. How do users configure another advisor?
>> >
>> >
>> >  After reconsideration, I would like to let PlanAdvisor be an internal
>> > interface, which is different from implementing a custom
>> connector/format.
>> >
>> > [1]
>> >
>> https://cwiki.apache.org/confluence/display/FLINK/FLIP-280%3A+Introduce+EXPLAIN+PLAN_ADVICE+to+provide+SQL+advice
>> > [2]
>> https://dev.mysql.com/doc/refman/8.0/en/explain.html#explain-analyze
>> > [3] https://www.postgresql.org/docs/current/sql-explain.html
>> > [4] https://prestodb.io/docs/current/sql/explain-analyze.html
>> > [5] https://docs.pingcap.com/tidb/dev/sql-statement-explain-analyze
>> >
>> > Best regards,
>> > Jane
>> >
>> > On Tue, Jan 3, 2023 at 6:20 PM Jingsong Li <jingsongl...@gmail.com>
>> wrote:
>> >
>> > > Thanks Jane for the FLIP! It looks very nice!
>> > >
>> > > Can you give examples of other systems for the syntax?
>> > > In other systems, is EXPLAIN ANALYZE already PHYSICAL_PLAN?
>> > >
>> > > `EXPLAIN ANALYZED_PHYSICAL_PLAN <query>` looks a bit strange, and even
>> > > stranger that it contains `advice`.
>> > >
>> > > The purpose of FLIP seems to be a bit more to `advice`, so can we just
>> > > introduce a syntax for `advice`?
>> > >
>> > > Best,
>> > > Jingsong
>> > >
>> > > On Tue, Jan 3, 2023 at 3:40 PM godfrey he <godfre...@gmail.com>
>> wrote:
>> > > >
>> > > > Thanks for driving this discussion.
>> > > >
>> > > > Do we really need to expose `PlanAnalyzerFactory` as public
>> interface?
>> > > > I prefer we only expose ExplainDetail#ANALYZED_PHYSICAL_PLAN and the
>> > > > analyzed result.
>> > > > Which is enough for users and consistent with the results of
>> `explain`
>> > > method.
>> > > >
>> > > > The classes about plan analyzer are in table planner module, which
>> > > > does not public api
>> > > > (public interfaces should be defined in flink-table-api-java
>> module).
>> > > > And PlanAnalyzer is depend on RelNode, which is internal class of
>> > > > planner, and not expose to users.
>> > > >
>> > > > Bests,
>> > > > Godfrey
>> > > >
>> > > >
>> > > > Shengkai Fang <fskm...@gmail.com> 于2023年1月3日周二 13:43写道:
>> > > > >
>> > > > > Sorry for the missing answer about the configuration of the
>> Analyzer.
>> > > Users
>> > > > > may don't need to configure this with SQL statements. In the SQL
>> > > Gateway,
>> > > > > users can configure the endpoints with the option
>> > > `sql-gateway.endpoint.type`
>> > > > > in the flink-conf.
>> > > > >
>> > > > > Best,
>> > > > > Shengkai
>> > > > >
>> > > > > Shengkai Fang <fskm...@gmail.com> 于2023年1月3日周二 12:26写道:
>> > > > >
>> > > > > > Hi, Jane.
>> > > > > >
>> > > > > > Thanks for bringing this to the discussion. I have some
>> questions
>> > > about
>> > > > > > the FLIP:
>> > > > > >
>> > > > > > 1. `PlanAnalyzer#analyze` uses the FlinkRelNode as the input.
>> Could
>> > > you
>> > > > > > share some thoughts about the motivation? In my experience,
>> users
>> > > mainly
>> > > > > > care about 2 things when they develop their job:
>> > > > > >
>> > > > > > a. Why their SQL can not work? For example, their streaming SQL
>> > > contains
>> > > > > > an OVER window but their ORDER key is not ROWTIME. In this
>> case, we
>> > > may
>> > > > > > don't have a physical node or logical node because, during the
>> > > > > > optimization, the planner has already thrown the exception.
>> > > > > >
>> > > > > > b. Many users care about whether their state is compatible after
>> > > upgrading
>> > > > > > their Flink version. In this case, I think the old execplan and
>> the
>> > > SQL
>> > > > > > statement are the user's input.
>> > > > > >
>> > > > > > So, I think we should introduce methods like
>> > > `PlanAnalyzer#analyze(String
>> > > > > > sql)` and `PlanAnalyzer#analyze(String sql, ExecnodeGraph)`
>> here.
>> > > > > >
>> > > > > > 2. I am just curious how other people add the rules to the
>> Advisor.
>> > > When
>> > > > > > rules increases, all these rules should be added to the Flink
>> > > codebase?
>> > > > > > 3. How do users configure another advisor?
>> > > > > >
>> > > > > > Best,
>> > > > > > Shengkai
>> > > > > >
>> > > > > >
>> > > > > >
>> > > > > > Jane Chan <qingyue....@gmail.com> 于2022年12月28日周三 12:30写道:
>> > > > > >
>> > > > > >> Hi @yuxia, Thank you for reviewing the FLIP and raising
>> questions.
>> > > > > >>
>> > > > > >> 1: Is the PlanAnalyzerFactory also expected to be implemented
>> by
>> > > users
>> > > > > >> just
>> > > > > >> > like DynamicTableSourceFactory or other factories? If so, I
>> > > notice that
>> > > > > >> in
>> > > > > >> > the code of PlanAnalyzerManager#registerAnalyzers, the code
>> is as
>> > > > > >> follows:
>> > > > > >> > FactoryUtil.discoverFactory(classLoader,
>> > > PlanAnalyzerFactory.class,
>> > > > > >> > StreamPlanAnalyzerFactory.STREAM_IDENTIFIER)); IIUC, it'll
>> always
>> > > find
>> > > > > >> the
>> > > > > >> > factory with the name
>> > > StreamPlanAnalyzerFactory.STREAM_IDENTIFIER; Is
>> > > > > >> it a
>> > > > > >> > typo or by design ?
>> > > > > >>
>> > > > > >>
>> > > > > >> This is a really good open question. For the short answer,
>> yes, it
>> > > is by
>> > > > > >> design. I'll explain the consideration in more detail.
>> > > > > >>
>> > > > > >> The standard procedure to create a custom table source/sink is
>> to
>> > > > > >> implement
>> > > > > >> the factory and the source/sink class. There is a strong 1v1
>> > > relationship
>> > > > > >> between the factory and the source/sink.
>> > > > > >>
>> > > > > >> SQL
>> > > > > >>
>> > > > > >> DynamicTableSourceFactory
>> > > > > >>
>> > > > > >> Source
>> > > > > >>
>> > > > > >> create table … with (‘connector’ = ‘foo’)
>> > > > > >>
>> > > > > >> #factoryIdentifer.equals(“foo”)
>> > > > > >>
>> > > > > >> FooTableSource
>> > > > > >>
>> > > > > >>
>> > > > > >> *Apart from that, the custom function module is another kind of
>> > > > > >> implementation. The factory creates a collection of functions.
>> This
>> > > is a
>> > > > > >> 1vN relationship between the factory and the functions.*
>> > > > > >>
>> > > > > >> SQL
>> > > > > >>
>> > > > > >> ModuleFactory
>> > > > > >>
>> > > > > >> Function
>> > > > > >>
>> > > > > >> load module ‘bar’
>> > > > > >>
>> > > > > >> #factoryIdentifier.equals(“bar”)
>> > > > > >>
>> > > > > >> A collection of functions
>> > > > > >>
>> > > > > >> Back to the plan analyzers, if we choose the first style, we
>> also
>> > > need to
>> > > > > >> expose a new SQL syntax to users, like "CREATE ANALYZER foo
>> WITH
>> > > ..." to
>> > > > > >> specify the factory identifier. But I think it is too heavy
>> because
>> > > an
>> > > > > >> analyzer is an auxiliary tool to help users write better
>> queries,
>> > > and thus
>> > > > > >> it should be exposed at the API level other than the user
>> syntax
>> > > level.
>> > > > > >>
>> > > > > >> As a result, I propose to follow the second style. Then we
>> don't
>> > > need to
>> > > > > >> introduce new syntax to create analyzers. Let
>> > > StreamPlanAnalyzerFactory be
>> > > > > >> the default factory to create analyzers under the streaming
>> mode,
>> > > and the
>> > > > > >> custom analyzers will register themselves in
>> > > StreamPlanAnalyzerFactory.
>> > > > > >>
>> > > > > >> @Override
>> > > > > >> public List<PlanAnalyzer> createAnalyzers() {
>> > > > > >>     return Arrays.asList(
>> > > > > >>             FooAnalyzer.INSTANCE,
>> > > > > >>             BarAnalyzer.INSTANCE,
>> > > > > >>             ...);
>> > > > > >> }
>> > > > > >>
>> > > > > >>
>> > > > > >> 2: Is there any special reason make PlanAdvice be a final
>> class?
>> > > Would it
>> > > > > >> > be better to make it an interface and we provide a default
>> > > > > >> implementation?
>> > > > > >> > My concern is some users may want have their own
>> implementation
>> > > for
>> > > > > >> > PlanAdvice. But it may be overthinking. If you think it won't
>> > > bring any
>> > > > > >> > problem, I'm also fine with that.
>> > > > > >>
>> > > > > >>
>> > > > > >> The reason why making PlanAdvice final is that I think users
>> would
>> > > prefer
>> > > > > >> to implement the custom PlanAnalyzer than PlanAdvice.
>> PlanAdvice is
>> > > a POJO
>> > > > > >> class to represent the analyzed result provided by
>> PlanAnalyzer.
>> > > > > >>
>> > > > > >>
>> > > > > >> 3: Is there a way only show advice? For me, it seems the advice
>> > > will be
>> > > > > >> > more useful and the nodes may contains to many details.
>> > > > > >>
>> > > > > >>
>> > > > > >> The result contains two parts: the optimized physical plan
>> itself +
>> > > the
>> > > > > >> analysis of the plan.
>> > > > > >>
>> > > > > >> For PlanAdvice with the scope as GLOBAL, it is possible to do
>> so.
>> > > While
>> > > > > >> for
>> > > > > >> a LOCAL scope, the advice content is specific to certain nodes
>> > > (E.g., some
>> > > > > >> certain rel nodes are sensitive to state TTL configuration).
>> In this
>> > > > > >> situation, the plan cannot be omitted. On the other hand, the
>> plan
>> > > is
>> > > > > >> necessary from the visualization perspective. During the PoC
>> phase,
>> > > I made
>> > > > > >> some attempts to adapt the Flink Visualizer to illustrate the
>> > > analyzed
>> > > > > >> plan, and it looks like the following pic. I think this is
>> > > intuitive to
>> > > > > >> help users understand their queries and what they can do
>> according
>> > > to the
>> > > > > >> advice.
>> > > > > >>
>> > > > > >>
>> > > > > >>
>> > > > > >> 4: I'm curious about what't the global advice will look like.
>> Is it
>> > > > > >> > possible to provide an example?
>> > > > > >>
>> > > > > >>
>> > > > > >> Here is an example to illustrate the non-deterministic update
>> issue.
>> > > > > >>
>> > > > > >> create temporary table cdc_with_meta (
>> > > > > >>   a int,
>> > > > > >>   b bigint,
>> > > > > >>   c string,
>> > > > > >>   d boolean,
>> > > > > >>   metadata_1 int metadata,
>> > > > > >>   metadata_2 string metadata,
>> > > > > >>   metadata_3 bigint metadata,
>> > > > > >>   primary key (a) not enforced
>> > > > > >> ) with (
>> > > > > >>   'connector' = 'values',
>> > > > > >>   'changelog-mode' = 'I,UA,UB,D',
>> > > > > >>   'readable-metadata' = 'metadata_1:INT, metadata_2:STRING,
>> > > > > >> metadata_3:BIGINT'
>> > > > > >> );
>> > > > > >>
>> > > > > >> create temporary table sink_without_pk (
>> > > > > >>   a int,
>> > > > > >>   b bigint,
>> > > > > >>   c string
>> > > > > >> ) with (
>> > > > > >>   'connector' = 'values',
>> > > > > >>   'sink-insert-only' = 'false'
>> > > > > >> );
>> > > > > >>
>> > > > > >> insert into sink_without_pk
>> > > > > >> select a, metadata_3, c
>> > > > > >> from cdc_with_meta;
>> > > > > >>
>> > > > > >> And with compilation as SCHEMA, the result is as below.
>> > > > > >>
>> > > > > >> {
>> > > > > >>   "nodes" : [ {
>> > > > > >>     "id" : 1,
>> > > > > >>     "type" : "StreamPhysicalTableSourceScan",
>> > > > > >>     "digest" : "TableSourceScan(table=[[default_catalog,
>> > > default_database,
>> > > > > >> cdc_with_meta, project=[a, c], metadata=[metadata_3]]],
>> fields=[a,
>> > > c,
>> > > > > >> metadata_3], upsertKeys=[[a]])",
>> > > > > >>     "changelog_mode" : "I,UB,UA,D"
>> > > > > >>   }, {
>> > > > > >>     "id" : 2,
>> > > > > >>     "type" : "StreamPhysicalCalc",
>> > > > > >>     "digest" : "Calc(select=[a, metadata_3, c],
>> upsertKeys=[[a]])",
>> > > > > >>     "changelog_mode" : "I,UB,UA,D",
>> > > > > >>     "predecessors" : [ {
>> > > > > >>       "id" : 1,
>> > > > > >>       "distribution" : "ANY",
>> > > > > >>       "changelog_mode" : "I,UB,UA,D"
>> > > > > >>     } ]
>> > > > > >>   }, {
>> > > > > >>     "id" : 3,
>> > > > > >>     "type" : "StreamPhysicalSink",
>> > > > > >>     "digest" :
>> > > > > >> "Sink(table=[default_catalog.default_database.sink_without_pk],
>> > > > > >> fields=[a, metadata_3, c])",
>> > > > > >>     "changelog_mode" : "NONE",
>> > > > > >>     "predecessors" : [ {
>> > > > > >>       "id" : 2,
>> > > > > >>       "distribution" : "ANY",
>> > > > > >>       "changelog_mode" : "I,UB,UA,D"
>> > > > > >>     } ]
>> > > > > >>   } ],
>> > > > > >>   "advice" : [ {
>> > > > > >>     "kind" : "WARNING",
>> > > > > >>     "scope" : "GLOBAL",
>> > > > > >>     "content" : "The metadata column(s): 'metadata_3' in cdc
>> source
>> > > may
>> > > > > >> cause wrong result or error on downstream operators, please
>> consider
>> > > > > >> removing these columns or use a non-cdc source that only has
>> insert
>> > > > > >> messages.\nsource
>> node:\nTableSourceScan(table=[[default_catalog,
>> > > > > >> default_database, cdc_with_meta, project=[a, c],
>> > > metadata=[metadata_3]]],
>> > > > > >> fields=[a, c, metadata_3], changelogMode=[I,UB,UA,D],
>> > > upsertKeys=[[a]])\n"
>> > > > > >>   } ]
>> > > > > >> }
>> > > > > >>
>> > > > > >>
>> > > > > >> Best regards,
>> > > > > >> Jane Chan
>> > > > > >>
>> > > > > >> On Tue, Dec 27, 2022 at 8:06 PM yuxia <
>> luoyu...@alumni.sjtu.edu.cn>
>> > > > > >> wrote:
>> > > > > >>
>> > > > > >> > Thanks for driving this FLIP. It should be a good
>> improvement to
>> > > users.
>> > > > > >> > But I have few questions:
>> > > > > >> > 1: Is the PlanAnalyzerFactory also expected to be
>> implemented by
>> > > users
>> > > > > >> > just like DynamicTableSourceFactory or other factories? If
>> so, I
>> > > notice
>> > > > > >> > that in the code of PlanAnalyzerManager#registerAnalyzers,
>> the
>> > > code is
>> > > > > >> as
>> > > > > >> > follows:
>> > > > > >> > FactoryUtil.discoverFactory(classLoader,
>> > > PlanAnalyzerFactory.class,
>> > > > > >> > StreamPlanAnalyzerFactory.STREAM_IDENTIFIER));
>> > > > > >> >
>> > > > > >> > IIUC, it'll always find the factory with the name
>> > > > > >> > StreamPlanAnalyzerFactory.STREAM_IDENTIFIER; Is it a typo or
>> by
>> > > design ?
>> > > > > >> >
>> > > > > >> > 2: Is there any special reason make PlanAdvice be a final
>> class?
>> > > Would
>> > > > > >> it
>> > > > > >> > be better to make it an interface and we provide a default
>> > > > > >> implementation?
>> > > > > >> > My concern is some users may want have their own
>> implementation
>> > > for
>> > > > > >> > PlanAdvice. But it may be overthinking. If you think it won't
>> > > bring any
>> > > > > >> > problem, I'm also fine with that.
>> > > > > >> >
>> > > > > >> > 3: Is there a way only show advice? For me, it seems the
>> advice
>> > > will be
>> > > > > >> > more useful and the nodes may contains to many details.
>> > > > > >> >
>> > > > > >> > 4: I'm curious about what't the global advice will look
>> like. Is
>> > > it
>> > > > > >> > possible to provide an example?
>> > > > > >> >
>> > > > > >>
>> > > > > >>
>> > > > > >>
>> > > > > >> >
>> > > > > >> > Best regards,
>> > > > > >> > Yuxia
>> > > > > >> >
>> > > > > >> > ----- 原始邮件 -----
>> > > > > >> > 发件人: "Jane Chan" <qingyue....@gmail.com>
>> > > > > >> > 收件人: "dev" <dev@flink.apache.org>
>> > > > > >> > 发送时间: 星期一, 2022年 12 月 26日 下午 9:39:18
>> > > > > >> > 主题: [DISCUSS] FLIP-280: Introduce a new explain mode to
>> provide
>> > > SQL
>> > > > > >> advice
>> > > > > >> >
>> > > > > >> > Hi, devs,
>> > > > > >> >
>> > > > > >> > I would like to start a discussion on FLIP-280: Introduce a
>> new
>> > > explain
>> > > > > >> > mode to provide SQL advice[1].
>> > > > > >> >
>> > > > > >> > Currently, Flink SQL EXPLAIN statement provides three
>> details to
>> > > display
>> > > > > >> > the plan. However, there is a considerable gap between the
>> current
>> > > > > >> > explained result and the actual, applicable actions for
>> users to
>> > > improve
>> > > > > >> > their queries.
>> > > > > >> >
>> > > > > >> > To provide more understandable, actionable advice closer to
>> the
>> > > user's
>> > > > > >> > perspective, we propose a new explain mode that analyzes the
>> > > physical
>> > > > > >> plan
>> > > > > >> > and attaches available tuning advice and data correctness
>> > > warnings.
>> > > > > >> >
>> > > > > >> > EXPLAIN ANALYZED_PHYSICAL_PLAN <query>
>> > > > > >> >
>> > > > > >> > I've included more details in [1], and I look forward to your
>> > > feedback.
>> > > > > >> >
>> > > > > >> > [1]
>> > > > > >> >
>> > > > > >> >
>> > > > > >>
>> > >
>> https://cwiki.apache.org/confluence/display/FLINK/FLIP-280%3A+Support+EXPLAIN+SQL+statements+with+advice
>> > > > > >> > [2] POC: https://github.com/LadyForest/flink/tree/FLIP-280
>> > > > > >> >
>> > > > > >> > Best regards,
>> > > > > >> > Jane Chan
>> > > > > >> >
>> > > > > >>
>> > > > > >
>> > >
>>
>

Reply via email to